
######################################################################
# REPLICATION MATERIALS
# TRUST IN THE JUDICIARY AND JUDICIAL CHECKS: EVIDENCE FROM ARGENTINA
######################################################################

### Packages needed to replicate the analyses
library(sandwich)
library(lmtest)
library(MASS)
library(margins)
library(marginaleffects)
library(fixest)
library(stargazer)
library(xtable)
library(kableExtra)
library(fastDummies)
library(corrplot)
library(ebal) # Entropy balancing
library(Matching) # Genetic matching
library(rgenoud)
library(parallel)
library(sensemakr) # Sensitivity analysis I
library(konfound) # Sensitivity analysis II
library(gtrendsR) # Google Trends figures
library(vdemdata) # Varieties of Democracy (V-Dem) dataset


options(scipen = 100)

# Set working directory
#dir <- ""
#setwd(dir)
#getwd()


# Create tables folder in working directory
if(!dir.exists("tab")){
  dir.create("tab")
}

# Create figures folder in working directory
if(!dir.exists("fig")){
  dir.create("fig")
}

# Create model results folder in working directory
if(!dir.exists("models")){
  dir.create("models")
}

# Create genetic matching output folder in working directory
if(!dir.exists("genetic-matching-output")){
  dir.create("genetic-matching-output")
}


############################################################################
################################ MAIN ANALYSES #############################
#### Main text Figures 2-6
#### Main text Tables 1-2
#### Appendix C
#### Appendix D
#### Appendix F
#### Appendix G
#### Appendix H
############################################################################


rm(list = ls())

# Load data
load("data/rizzo.RData")

# Dataset with limited set of covariates
sel_lim <-	!is.na(rizzo$Tr) &
  !is.na(rizzo$party2) &
  !is.na(rizzo$age) &
  !is.na(rizzo$trustbi) &
  !is.na(rizzo$female) &
  !is.na(rizzo$education) &
  !is.na(rizzo$SES_ord) &
  !is.na(rizzo$subinc_ord) &
  !is.na(rizzo$class_ord) &
  !is.na(rizzo$religion) &
  !is.na(rizzo$city)

table(sel_lim)
rizzo_limited <- rizzo[sel_lim,]
dim(rizzo_limited)

## Subset by lower court and supreme court conditions
  # In each data frame, control: Tr=0 and court ruling (lower or supreme): Tr=1
table(rizzo_limited$date, rizzo_limited$Tr)
# Lower court: rizzo1
rizzo1_lim <- rizzo_limited[rizzo_limited$Tr != 2, ]
# Lower court: rizzo1
rizzo2_lim <- rizzo_limited[rizzo_limited$Tr != 1, ]
rizzo2_lim$Tr <- ifelse(rizzo2_lim$Tr == 2, 1, 0)

## # Dataset with extensive set of covariates
sel_ext <-	!is.na(rizzo$Tr) &
  !is.na(rizzo$party2) &
  !is.na(rizzo$age) &
  !is.na(rizzo$trustbi) &
  !is.na(rizzo$female) &
  !is.na(rizzo$education) &
  !is.na(rizzo$SES_ord) &
  !is.na(rizzo$subinc_ord) &
  !is.na(rizzo$class_ord) &
  !is.na(rizzo$religion) &
  !is.na(rizzo$city) &
  !is.na(rizzo$know) &
  !is.na(rizzo$polint) &
  !is.na(rizzo$TV_freq) &
  !is.na(rizzo$newspaper_freq) &
  !is.na(rizzo$internet_freq)

table(sel_ext)
rizzo_extensive <- rizzo[sel_ext,]
dim(rizzo_extensive)

## Extensive data set
table(rizzo_extensive$date, rizzo_extensive$Tr)
rizzo1_ext <- rizzo_extensive[rizzo_extensive$Tr != 2, ]
rizzo2_ext <- rizzo_extensive[rizzo_extensive$Tr != 1, ]
rizzo2_ext$Tr <- ifelse(rizzo2_ext$Tr == 2, 1, 0)


###############################
# Descriptive statistics
###############################


########################################
### Main text: Figure 2: Distribution of respondents

#png(file = "fig/png-figures/distribution-respondents.png", width = 8, height = 4, units = "in", res = 600)
#tiff(file = "fig/tiff-figures/distribution-respondents.tif", width = 8, height = 4, units = "in", res = 600)
pdf(file = "fig/distribution-respondents.pdf",
    width = 8, # The width of the plot in inches
    height = 4) # The height of the plot in inches
par(mar=c(2, 4, 0, 0), oma=c(0, 0, 0, 0))

hist(rizzo$date, 45, main = "", 
     xlab = "", ylab = "# Respondents", ylim = c(0,112),
     xaxt="n")
axis(1, at = c(1.25,5.8,10.75,17.75,23.75,29.75), 
     labels = c(1,6,11,18,25,30),
     padj = 0.8, # x labels position
     cex.axis=1.2, tick=FALSE, pos = 8)

title(xlab = "June 2013", line = 1, cex.lab = 1.2)

segments(x0=c(10.75, 17.75), x1=c(10.75, 17.75), 
         y0=c(0.75,0.75), y1=c(108,108), 
         lty = 2, lwd = 2.5)

text(10, 112.5,"6/11 Lower Court",
     cex = 1.25)
text(19, 111.5,"6/18 Supreme Court", 
     cex = 1.25)
dev.off()

########################################
### Main text: Figure 3: Distribution of Outcome

#png(file = "fig/png-figures/outcome-distributions.png", width = 10, height = 3, units = "in", res = 600)
#tiff(file = "fig/png-figures/outcome-distributions.tif", width = 10, height = 3, units = "in", res = 600)
pdf(file = "fig/outcome-distributions.pdf",   
    width = 10, # The width of the plot in inches
    height = 3) # The height of the plot in inches
par(mar=c(2, 4, 2.5, 0), oma=c(1, 1, 0, 1)) # Set up margins by number of lines
layout(matrix(1:2, ncol=2), # 2-panel figure
       widths=c(1, 1))

binary_tab <- table(rizzo$trustbi)
barplot(binary_tab,
        names.arg=c("None/A Little", "Some/A Lot"),
        cex.names=1.3,
        main = "Binary", ylab = "Frequency",
        #width = c(0.25,0.25,0.25), 
        space = 0.35, # more space between bars
        xlim = c(0, 3), # centers 2 bars
        axes = TRUE)
        
ordinal_tab <- table(rizzo$trust)
barplot(ordinal_tab,
        names.arg=c("None", "A Little", "Some", "A Lot"),
        cex.names=1.3,
        main = "Ordinal", ylab = "Frequency",
        width = c(0.25,0.25,0.25,0.25), xlim = c(0,1.25))

dev.off()

########################################
### Main text: Table 1: Covariate balance

# Mean, sd, and n by Treatment group

# Create matrix to store values
tab_lim <- as.data.frame(matrix(NA, 21, 8))
colnames(tab_lim) <- c("mean1","sd1","mean2","sd2","mean3","sd3",
                       "p-value1","p-value2")
rownames(tab_lim) <- c("Gov. Supporter", "Age", "Female", "Education",
                       "SES (Bad/Very bad)", "SES (Not bad)", "SES (Good)", 
                       "SES (Very good)", 
                       "Insuff. and problems", "Insufficient", 
                       "Just sufficient", "Suff. and save",
                       "Lower", "Middle-lower", "Middle", "Middle-upper",
                       "Agnostic/Atheist/None/No answer", "Catholic", 
                       "Evangelical", "Other", "N")

control <- rizzo1_lim[rizzo1_lim$Tr == 0, ]
lower <- rizzo1_lim[rizzo1_lim$Tr == 1, ]
supreme <- rizzo2_lim[rizzo2_lim$Tr == 1, ]

rizzo_balance <- list("control" = control, "lower" = lower, "supreme" = supreme)

for(i in seq_along(rizzo_balance)){
  dat <- rizzo_balance[[i]]
  group <- names(rizzo_balance[i])
  if(group == "control"){
    col <- 1
  }
  if(group == "lower"){
    col <- 3
  }
  if(group == "supreme"){
    col <- 5
  }
  
  # Means
  tab_lim[1,col] <- round(mean(dat$party2, na.rm = TRUE), 3)
  tab_lim[2,col] <- round(mean(dat$age, na.rm = TRUE), 3)
  tab_lim[3,col] <- round(mean(dat$female, na.rm = TRUE), 3)
  tab_lim[4,col] <- round(mean(dat$education, na.rm = TRUE), 3)
  
  tab_lim[5,col] <- round(mean(dat$SES_ord == "Bad/Very bad", na.rm = TRUE), 3)
  tab_lim[6,col] <- round(mean(dat$SES_ord == "Not bad", na.rm = TRUE), 3)
  tab_lim[7,col] <- round(mean(dat$SES_ord == "Good", na.rm = TRUE), 3)
  tab_lim[8,col] <- round(mean(dat$SES_ord == "Very good", na.rm = TRUE), 3)
  
  tab_lim[9,col] <- round(mean(dat$subinc_ord == "Not suff-big problems", na.rm = TRUE), 3)
  tab_lim[10,col] <- round(mean(dat$subinc_ord == "Not suff", na.rm = TRUE), 3)
  tab_lim[11,col] <- round(mean(dat$subinc_ord == "Just suff", na.rm = TRUE), 3)
  tab_lim[12,col] <- round(mean(dat$subinc_ord == "Suff-save", na.rm = TRUE), 3)
  
  tab_lim[13,col] <- round(mean(dat$class_ord == "Lower", na.rm = TRUE), 3)
  tab_lim[14,col] <- round(mean(dat$class_ord == "Middle-lower", na.rm = TRUE), 3)
  tab_lim[15,col] <- round(mean(dat$class_ord == "Middle", na.rm = TRUE), 3)
  tab_lim[16,col] <- round(mean(dat$class_ord == "Middle/Upper", na.rm = TRUE), 3)
  
  tab_lim[17,col] <- round(mean(dat$religion == "Agnostico/Ateo/Ninguna/No answer", na.rm = TRUE), 3)
  tab_lim[18,col] <- round(mean(dat$religion == "Catolica", na.rm = TRUE), 3)
  tab_lim[19,col] <- round(mean(dat$religion == "Evangelica", na.rm = TRUE), 3)
  tab_lim[20,col] <- round(mean(dat$religion == "Otra", na.rm = TRUE), 3)
  
  # sd
  tab_lim[1,col+1] <- round(sd(dat$party2, na.rm = TRUE), 3)
  tab_lim[2,col+1] <- round(sd(dat$female, na.rm = TRUE), 3)
  tab_lim[3,col+1] <- round(sd(dat$age, na.rm = TRUE), 3)
  tab_lim[4,col+1] <- round(sd(dat$education, na.rm = TRUE), 3)
  
  tab_lim[5,col+1] <- round(sd(dat$SES_ord == "Bad/Very bad", na.rm = TRUE), 3)
  tab_lim[6,col+1] <- round(sd(dat$SES_ord == "Not bad", na.rm = TRUE), 3)
  tab_lim[7,col+1] <- round(sd(dat$SES_ord == "Good", na.rm = TRUE), 3)
  tab_lim[8,col+1] <- round(sd(dat$SES_ord == "Very good", na.rm = TRUE), 3)
  
  tab_lim[9,col+1] <- round(sd(dat$subinc_ord == "Not suff-big problems", na.rm = TRUE), 3)
  tab_lim[10,col+1] <- round(sd(dat$subinc_ord == "Not suff", na.rm = TRUE), 3)
  tab_lim[11,col+1] <- round(sd(dat$subinc_ord == "Just suff", na.rm = TRUE), 3)
  tab_lim[12,col+1] <- round(sd(dat$subinc_ord == "Suff-save", na.rm = TRUE), 3)
  
  tab_lim[13,col+1] <- round(sd(dat$class_ord == "Lower", na.rm = TRUE), 3)
  tab_lim[14,col+1] <- round(sd(dat$class_ord == "Middle-lower", na.rm = TRUE), 3)
  tab_lim[15,col+1] <- round(sd(dat$class_ord == "Middle", na.rm = TRUE), 3)
  tab_lim[16,col+1] <- round(sd(dat$class_ord == "Middle/Upper", na.rm = TRUE), 3)
  
  tab_lim[17,col+1] <- round(sd(dat$religion == "Agnostico/Ateo/Ninguna/No answer", na.rm = TRUE), 3)
  tab_lim[18,col+1] <- round(sd(dat$religion == "Catolica", na.rm = TRUE), 3)
  tab_lim[19,col+1] <- round(sd(dat$religion == "Evangelica", na.rm = TRUE), 3)
  tab_lim[20,col+1] <- round(sd(dat$religion == "Otra", na.rm = TRUE), 3)
  
  # n
  tab_lim[21,col] <- nrow(dat)
}

tab_lim

### Exact p-values using randomization inference

# Create tr indicator across three conditions
control$group <- 0
lower$group <- 1
supreme$group <- 2

## Stack group datasets
rizzo_RI <- rbind(control, lower, supreme)

# Create dummies for ordinal/categorical covariates
rizzo_RI <- dummy_cols(rizzo_RI, select_columns = c("SES_ord", "subinc_ord", 
                                                    "class_ord", "religion"))
names(rizzo_RI)
names(rizzo_RI)[45:60]
names(rizzo_RI)[45:60] <- gsub("[-/ ]", "_", names(rizzo_RI)[45:60])
names(rizzo_RI)[45:60]

# Covariates to loop over
covars <- c("party2", "age", "female", "education", names(rizzo_RI[45:60]))
covars

# 100,000 random samples
sample <- 100000

# Computation takes about 25-30 minutes
start.time <- Sys.time()

nCores <- detectCores()-1
pcores <- makeCluster(nCores) #making parallel cluster

set.seed(1)
for(i in c(2,1)){
  sel <- rizzo_RI$group != i
  dat.temp <- rizzo_RI[sel,]
  
  if(i==1){
    dat.temp$group <- ifelse(dat.temp$group == 2, 1, 0)
  }
  
  # Prob assigned treatment
  p <- sum(dat.temp$group)/nrow(dat.temp)
  
  for(j in seq_along(covars)){
    x <- covars[j]
    # Substitute in correct covariate
    f <- as.formula(paste(x, "~ group"))
    # Compute observed T-statistic
    out <- lm(f, data = dat.temp)
    T.obs <- abs(out$coef[2])
    
    # Set loop
    T.RI <- rep(NA,sample)
    f <- as.formula(paste(x, "~ Tr.RI"))
    m <- 1
    
    for(m in 1:sample)	{
      
      dat.temp$Tr.RI <- rbinom(nrow(dat.temp), 1, p)
      table(dat.temp$Tr.RI)
      out <- lm(f, data = dat.temp)
      T.RI[m] <- abs(out$coef[2])
      
      if(m %% 10000 == 0)	{cat(m,"\n")} 
    }
    print(paste0("covariate: ", x, " | omit: ", i))
    # Compute corresponding exact p-values and store in dataframe "tab_lim"
      # See Young (2019)
    if(i == 2)		{
      tab_lim[j,7] <- round(1/(sample+1) * sum(T.RI > T.obs) + 
                              runif(1) * 1/(sample+1)* (1+sum(T.RI == T.obs)), 3)
    }
    if(i == 1)		{
      tab_lim[j,8] <- round(1/(sample+1) * sum(T.RI > T.obs) + 
                              runif(1) * 1/(sample+1)* (1+sum(T.RI == T.obs)), 3)
    }
  }
}

stopCluster(pcores)

end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken

tab_lim

## Build covariate balance table
balance <- as.data.frame(tab_lim)
balance

col_names <- c("",  
               "\\multicolumn{1}{c}{Mean}", "\\multicolumn{1}{c}{sd}",
               "\\multicolumn{1}{c}{Mean}", "\\multicolumn{1}{c}{sd}",
               "\\multicolumn{1}{c}{Mean}", "\\multicolumn{1}{c}{sd}",
               "\\multicolumn{1}{c}{\\makecell[c]{Lower vs\\\\Control}}", 
               "\\multicolumn{1}{c}{\\makecell[c]{Supreme vs\\\\Control}}")

top_headers <- c(" " = 1,        
                 "Control" = 2, 
                 "Lower C." = 2, 
                 "Supreme C." = 2, 
                 "(exact) \\textit{p}-value" = 2)

# Format last row ("N")
N_row <- balance[nrow(balance), ]
N_row[1] <- "\\multicolumn{2}{c}{101}"
N_row[2] <- ""
N_row[3] <- "\\multicolumn{2}{c}{185}"
N_row[4] <- ""
N_row[5] <- "\\multicolumn{2}{c}{174}"
N_row[6] <- ""
N_row[7] <- ""  # last two columns empty
N_row[8] <- ""

# Replace last row in balance with this
balance[nrow(balance), ] <- N_row

balance_tab <- kable(balance,
                     format = "latex",
                     booktabs = TRUE,
                     col.names = col_names,
                     #align = align_vec,
                     align = c("*{8}", "{d{1.3}}", rep("", 7)),
                     escape = FALSE,
                     linesep = "") %>%
  add_header_above(top_headers, escape = FALSE) %>%
  kable_styling(latex_options = "HOLD_position")
balance_tab

# Clean last row
balance_tab <- gsub("N &", " \\\\midrule N &", balance_tab)  
balance_tab <- gsub(" &  & ", " & ", balance_tab)

footnote <- "\\multicolumn{9}{l}{\\small \\parbox[t]{1.2\\textwidth}{\\textit{Note:} The table shows means and exact \\textit{p}-values (Young 2019) using randomization inference tests with 100,000 random samples.}} \\\\"

# Append footnote text
balance_tab <- paste0(balance_tab, footnote)
cat(balance_tab)
# Save table
writeLines(balance_tab, "tab/covariate-balance.tex")


################################################
############# Statistical analyses #############
################################################


# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

#################################################
#### Main text results: table 2 and figure 4 ####
#################################################

## Limited set of covariates and province fixed effects
  # Covariates that are almost certainly not post-treatment 
f_OLS_lim <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(prov)")

## Lower court
m_OLS_lim_low <- lm(f_OLS_lim, data = rizzo1_lim)

## Supreme court
m_OLS_lim_sup <- lm(f_OLS_lim, data = rizzo2_lim)

### Save models for tables and figure
OLS_lim <- list("OLS_lim_lower" = m_OLS_lim_low, "OLS_lim_supreme" = m_OLS_lim_sup, 
                   "rizzo1_lim" = rizzo1_lim, "rizzo2_lim" = rizzo2_lim)
save(OLS_lim, file = "models/OLS-limited-covariates.RData")

###########
### Entropy balance + WLS models (binary outcome)
###########

## Lower Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_lim_low <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo1_lim))
)

colnames(EB_lim_low)

  # Remove intercept
EB_lim_low <- EB_lim_low[, -1]

colnames(EB_lim_low)

  # Add in outcomes and missing variables
EB_lim_low <- cbind("trustbi" = rizzo1_lim$trustbi, 
                 "city" = rizzo1_lim$city, # City (clustered SEs and city FE)
                 "date" = rizzo1_lim$date, # Date of interview (clustered SEs)
                 "prov" = rizzo1_lim$prov, # Province (province FE)
                 EB_lim_low, # Covariate matrix
                 "trustord" = rizzo1_lim$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo1_lim$trust)  # scaled outcome (appendix analysis)
names(EB_lim_low)

  # Order observations to add entropy balance weights (controls first)
EB_lim_low <- rbind(EB_lim_low[EB_lim_low$Tr == 0,],EB_lim_low[EB_lim_low$Tr == 1,])

colnames(EB_lim_low)

# Compute entropy balance (EB) weights
out1_lim <- ebalance(Treatment = EB_lim_low$Tr, 
                     X = EB_lim_low[,6:21]) # include only covariates to balance on

# Add weights to (ordered) dataset
EB_lim_low$w <- c(out1_lim$w, # weights for control observations 
                  rep(1, nrow(EB_lim_low[EB_lim_low$Tr == 1,])))

# Check distribution of weights
hist(out1_lim$w, 100) # weights are well behaved

names(EB_lim_low)

# Formula for regressions with limited covariate dataset
names(EB_lim_low)
f_EB_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                       paste0(paste0(names(EB_lim_low)[7:21], collapse = " + "), 
                              " + factor(prov)")))

# WLS with bias adjustment
m_EB_lim_low <- lm(f_EB_lim, data = EB_lim_low, weights = w)


## Supreme Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_lim_sup <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_lim))
)

colnames(EB_lim_sup)

  # Remove intercept
EB_lim_sup <- EB_lim_sup[, -1]

colnames(EB_lim_sup)

  # Add in outcomes and missing variables
EB_lim_sup <- cbind("trustbi" = rizzo2_lim$trustbi, 
                 "city" = rizzo2_lim$city, # City (clustered SEs and city FE)
                 "date" = rizzo2_lim$date, # Date of interview (clustered SEs)
                 "prov" = rizzo2_lim$prov, # Province (province FE)
                 EB_lim_sup, # Covariate matrix
                 "trustord" = rizzo2_lim$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo2_lim$trust)  # scaled outcome (appendix analysis)
names(EB_lim_sup)

  # Order observations to add entropy balance weights (controls first)
EB_lim_sup <- rbind(EB_lim_sup[EB_lim_sup$Tr == 0,],EB_lim_sup[EB_lim_sup$Tr == 1,])

colnames(EB_lim_sup)

# Compute entropy balance (EB) weights
out2_lim <- ebalance(Treatment = EB_lim_sup$Tr, 
                     X = EB_lim_sup[,6:21]) # include only covariates to balance on

# Check distribution of weights
hist(out2_lim$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_lim_sup$w <- c(out2_lim$w, # weights for control observations 
                  rep(1, nrow(EB_lim_sup[EB_lim_sup$Tr == 1,])))

# WLS with bias adjustment
m_EB_lim_sup <- lm(f_EB_lim, data = EB_lim_sup, weights = w)


### Save models for tables and figure
EB_lim <- list("EB_lim_lower" = m_EB_lim_low, "EB_lim_supreme" = m_EB_lim_sup, 
                "EB_lim_low" = EB_lim_low, "EB_lim_sup" = EB_lim_sup)
save(EB_lim, file = "models/EB-limited-covariates.RData")


###########
### Genetic matching + WLS models (binary outcome)
###########

## Lower Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out1_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + factor(prov)
                   , 
                   family = binomial(link = "probit"), data = rizzo1_lim)
e <- fitted(ps.out1_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match1_lim <- data.frame(model.matrix(ps.out1_lim))
names(match1_lim)
  # Remove intercept and prov
match1_lim <- match1_lim[,-c(1, 18:28)]
names(match1_lim)
  # Add linearized estimated propensity scores
match1_lim$l <- l
names(match1_lim)
  # Add in other variables
match1_lim <- cbind("trustbi" = rizzo1_lim$trustbi, 
                    "Tr" = rizzo1_lim$Tr, 
                    "city" = rizzo1_lim$city, # City (clustered SEs and city FE)
                    "date" = rizzo1_lim$date, # Date of interview (clustered SEs)
                    "prov" = rizzo1_lim$prov, # Province (province FE)
                    match1_lim, 
                    "trustord" = rizzo1_lim$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo1_lim$trust)  # scaled outcome (appendix analysis))
names(match1_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 25 minutes
  # Solution Found Generation 6
  # Number of Generations Run 57
set.seed(1)
gm.out1_lim <-	GenMatch(Tr = match1_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match1_lim[, c(6:22)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out1_lim, file = "genetic-matching-output/gen-match-output-lower-lim.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-lower-lim.RData")

names(match1_lim)

# Use Match() to obtain dataset of matched observations
mout1_lim <- Match(Y = match1_lim$trustbi, 
                  Tr = match1_lim$Tr, 
                  # Include only covariates (and linearized estimated propensity scores)
                  X = match1_lim[, c(6:22)], 
                  Weight.matrix = gm.out1_lim,
                  BiasAdjust = T,
                  ties=T, 
                  replace=T)

# Vectors of matched control and treated observations
sel <- c(mout1_lim$index.treated, mout1_lim$index.control)
# Create dataset of matches
GM_lim_low <- match1_lim[sel,]
# Add weights
GM_lim_low$w <- c(mout1_lim$weights, mout1_lim$weights)

##  GM + WLS with bias adjustment
names(GM_lim_low)

# Formula for regressions with limited covariate dataset
f_GM_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_lim_low)[7:21], collapse = " + "), 
                                     " + factor(prov)")))

m_GM_lim_low <- lm(f_GM_lim, data = GM_lim_low, weights = w)


## Supreme Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out2_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + factor(prov)
                   , 
                   family = binomial(link = "probit"), data = rizzo2_lim)
e <- fitted(ps.out2_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match2_lim <- data.frame(model.matrix(ps.out2_lim))
names(match2_lim)
  # Remove intercept and prov
match2_lim <- match2_lim[,-c(1, 18:29)]
names(match2_lim)
  # Add linearized estimated propensity scores
match2_lim$l <- l
names(match2_lim)
  # Add in other variables
match2_lim <- cbind("trustbi" = rizzo2_lim$trustbi, 
                    "Tr" = rizzo2_lim$Tr, 
                    "city" = rizzo2_lim$city, # City (clustered SEs and city FE)
                    "date" = rizzo2_lim$date, # Date of interview (clustered SEs)
                    "prov" = rizzo2_lim$prov, # Province (province FE)
                    match2_lim, 
                    "trustord" = rizzo2_lim$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo2_lim$trust)  # scaled outcome (appendix analysis))
names(match2_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 5 minutes
  # Solution Found Generation 73
  # Number of Generations Run 124
set.seed(1)
gm.out2_lim <-	GenMatch(Tr = match2_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match2_lim[, c(6:22)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out2_lim, file = "genetic-matching-output/gen-match-output-supreme-lim.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-supreme-lim.RData")

names(match2_lim)

# Use Match() to obtain dataset of matched observations
mout2_lim <- Match(Tr = match2_lim$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match2_lim[, c(6:22)], 
                   Weight.matrix = gm.out2_lim,
                   ties=T,
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_lim$index.treated, mout2_lim$index.control)
# Create dataset of matches
GM_lim_sup <- match2_lim[sel,]
# Add weights
GM_lim_sup$w <- c(mout2_lim$weights, mout2_lim$weights)

##  GM + WLS with bias adjustment
m_GM_lim_sup <- lm(f_GM_lim, data = GM_lim_sup, weights = w)

### Save models for tables and figure
GM_lim <- list("GM_lim_lower" = m_GM_lim_low, "GM_lim_supreme" = m_GM_lim_sup, 
               "GM_lim_low" = GM_lim_low, "GM_lim_sup" = GM_lim_sup)
save(GM_lim, file = "models/GM-limited-covariates.RData")


###########################################
# Main text: Table 2

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call OLS models
load("models/OLS-limited-covariates.RData")
# Call entropy balancing binary models
load("models/EB-limited-covariates.RData")
# Call genetic matching models
load("models/GM-limited-covariates.RData")

names(OLS_lim)
names(EB_lim)
names(GM_lim)

# Lower Court models (limited set of covariates)
m1 <- OLS_lim[["OLS_lim_lower"]] # OLS model

m2 <- EB_lim[["EB_lim_lower"]] # EB model
EB_lim_low <- EB_lim[["EB_lim_low"]] # EB dataset

m3 <- GM_lim[["GM_lim_lower"]] # GM model
GM_lim_low <- GM_lim[["GM_lim_low"]] # GM dataset

# Supreme Court models (limited set of covariates)
m4 <- OLS_lim[["OLS_lim_supreme"]] # OLS model

m5 <- EB_lim[["EB_lim_supreme"]] # EB model
EB_lim_sup <- EB_lim[["EB_lim_sup"]] # EB dataset

m6 <- GM_lim[["GM_lim_supreme"]] # GM model
GM_lim_sup <- GM_lim[["GM_lim_sup"]] # GM dataset

## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = ~ city + date, type = "HC1"))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = ~ city + date, type = "HC1"))[,2]
se3 <- coeftest(m3, vcovCL(m3, cluster = ~ city + date, type = "HC1"))[,2]
se4 <- coeftest(m4, vcovCL(m4, cluster = ~ city + date, type = "HC1"))[,2]
se5 <- coeftest(m5, vcovCL(m5, cluster = ~ city + date, type = "HC1"))[,2]
se6 <- coeftest(m6, vcovCL(m6, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1$resid + m1$fitted.values), 
                 mean(m2$resid + m2$fitted.values),
                 mean(m3$resid + m3$fitted.values),
                 mean(m4$resid + m4$fitted.values),
                 mean(m5$resid + m5$fitted.values),
                 mean(m6$resid + m6$fitted.values)),3)
Y_sd <- round(c(sd(m1$resid + m1$fitted.values), 
                sd(m2$resid + m2$fitted.values),
                sd(m3$resid + m3$fitted.values),
                sd(m4$resid + m4$fitted.values),
                sd(m5$resid + m5$fitted.values),
                sd(m6$resid + m6$fitted.values)),3)

## Create main text table
main_tab <- stargazer(m1, m2, m3, m4, m5, m6,
                        se=list(se1, se2, se3, se4, se5, se6),
                        title="Main Results", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:main",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("Tr", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{0.95\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                         c("sd(Trust)", Y_sd),
                                         c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("Province FE?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"))
                      )
# Format table
main_tab
main_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", main_tab, fixed=TRUE)
main_tab <- gsub("\\hline \\\\[-1.8ex] ", "", main_tab, fixed=TRUE)
main_tab <- gsub("\\hline ", "\\bottomrule", main_tab, fixed=TRUE)
main_tab <- gsub("[-1.8ex] ", "", main_tab, fixed=TRUE)
main_tab <- gsub("  \\label{tab:main} ", 
                 "\\tabcolsep=8pt  \\label{tab:main}  \\resizebox{\\linewidth}{!}{%", main_tab, fixed=TRUE)
main_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", main_tab, fixed=TRUE)
main_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                 "\\begin{tabular}{l*{6}{d{1.3}}}", main_tab, fixed=TRUE)
main_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                 " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", main_tab, fixed=TRUE)
main_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                 "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", main_tab, fixed=TRUE)
main_tab <- gsub("[-1.8ex]", "", main_tab, fixed=TRUE)
main_tab

sink("tab/main-results.tex")
cat(main_tab, sep="\n")
sink()

###########################################
# Main text: Figure 4

# Compute vcov matrices
vcov1 <- vcovCL(m1, cluster = ~ city + date, type = "HC1")
vcov2 <- vcovCL(m2, cluster = ~ city + date, type = "HC1")
vcov3 <- vcovCL(m3, cluster = ~ city + date, type = "HC1")
vcov4 <- vcovCL(m4, cluster = ~ city + date, type = "HC1")
vcov5 <- vcovCL(m5, cluster = ~ city + date, type = "HC1")
vcov6 <- vcovCL(m6, cluster = ~ city + date, type = "HC1")

# Data frame to store values in
data_fig <- matrix(NA, 12, 12)
colnames(data_fig) <- c("factor", "party", "AME", "SE", "z", "p", "lower95", 
                        "upper95", "lower90", "upper90", "model", "Tr")
data_fig <- as.data.frame(data_fig)
head(data_fig)

#### OLS
data_fig[1:4, 11] <- "OLS"
## Lower court
data_fig[1:2,1:8] <- summary(margins(m1, variables = "Tr", at = list(party2 = 0:1), 
                                     vcov = vcov1))
data_fig[1,9:10] <- confint(margins(m1, variables = "Tr", at = list(party2 = 0), 
                                    vcov = vcov1), level = 0.90)
data_fig[2,9:10] <- confint(margins(m1, variables = "Tr", at = list(party2 = 1), 
                                    vcov = vcov1), level = 0.90)
data_fig[1:2, 12] <- "lower"
head(data_fig)

## Supreme court
data_fig[3:4,1:8] <- summary(margins(m4, variables = "Tr", at = list(party2 = 0:1), 
                                     vcov = vcov4))
data_fig[3,9:10] <- confint(margins(m4, variables = "Tr", at = list(party2 = 0), 
                                    vcov = vcov4), level = 0.90)
data_fig[4,9:10] <- confint(margins(m4, variables = "Tr", at = list(party2 = 1), 
                                    vcov = vcov4), level = 0.90)
data_fig[3:4, 12] <- "supreme"
head(data_fig)

#### Entropy Balancing (EB) + WLS
data_fig[5:8, 11] <- "EB"
## Lower
data_fig[5:6,1:8] <- summary(margins(m2, variables = "Tr", at = list(party2 = 0:1), 
                                     vcov = vcov2))
data_fig[5,9:10] <- confint(margins(m2, variables = "Tr", at = list(party2 = 0), 
                                    vcov = vcov2), level = 0.90)
data_fig[6,9:10] <- confint(margins(m2, variables = "Tr", at = list(party2 = 1), 
                                    vcov = vcov2), level = 0.90)
data_fig[5:6, 12] <- "lower"
head(data_fig)

## Supreme
data_fig[7:8,1:8] <- summary(margins(m5, variables = "Tr", at = list(party2 = 0:1), 
                                     vcov = vcov5))
data_fig[7,9:10] <- confint(margins(m5, variables = "Tr", at = list(party2 = 0), 
                                    vcov = vcov5), level = 0.90)
data_fig[8,9:10] <- confint(margins(m5, variables = "Tr", at = list(party2 = 1), 
                                    vcov = vcov5), level = 0.90)
data_fig[7:8, 12] <- "supreme"
data_fig

#### Genetic Matching (GM) + WLS
data_fig[9:12, 11] <- "GM"
## Lower
data_fig[9:10,1:8] <- summary(margins(m3, variables = "Tr", at = list(party2 = 0:1), 
                                      vcov = vcov3))
data_fig[9,9:10] <- confint(margins(m3, variables = "Tr", at = list(party2 = 0), 
                                    vcov = vcov3), level = 0.90)
data_fig[10,9:10] <- confint(margins(m3, variables = "Tr", at = list(party2 = 1), 
                                     vcov = vcov3), level = 0.90)
data_fig[9:10, 12] <- "lower"
data_fig

## Supreme
data_fig[11:12,1:8] <- summary(margins(m6, variables = "Tr", at = list(party2 = 0:1), 
                                       vcov = vcov6))
data_fig[11,9:10] <- confint(margins(m6, variables = "Tr", at = list(party2 = 0), 
                                     vcov = vcov6), level = 0.90)
data_fig[12,9:10] <- confint(margins(m6, variables = "Tr", at = list(party2 = 1), 
                                     vcov = vcov6), level = 0.90)
data_fig[11:12, 12] <- "supreme"
data_fig

#### OLS
# point estimates
OLSpe <- c(data_fig$AME[data_fig$model=="OLS" & data_fig$party==0], # opposition supp
           data_fig$AME[data_fig$model=="OLS" & data_fig$party==1]) # government supp
# 95 CIs
OLS95u <- c(data_fig$upper95[data_fig$model=="OLS" & data_fig$party==0], # opposition supp
            data_fig$upper95[data_fig$model=="OLS" & data_fig$party==1]) # government supp
OLS95l <- c(data_fig$lower95[data_fig$model=="OLS" & data_fig$party==0], # opposition supp
            data_fig$lower95[data_fig$model=="OLS" & data_fig$party==1]) # government supp
# 90 CIs
OLS90u <- c(data_fig$upper90[data_fig$model=="OLS" & data_fig$party==0], # opposition supp
            data_fig$upper90[data_fig$model=="OLS" & data_fig$party==1])
OLS90l <- c(data_fig$lower90[data_fig$model=="OLS" & data_fig$party==0], # opposition supp
            data_fig$lower90[data_fig$model=="OLS" & data_fig$party==1]) # government supp

#### EB
# point estimates
EBpe <- c(data_fig$AME[data_fig$model=="EB" & data_fig$party==0], # opposition supp
          data_fig$AME[data_fig$model=="EB" & data_fig$party==1]) # government supp
# 95 CIs
EB95u <- c(data_fig$upper95[data_fig$model=="EB" & data_fig$party==0], # opposition supp
           data_fig$upper95[data_fig$model=="EB" & data_fig$party==1]) # government supp
EB95l <- c(data_fig$lower95[data_fig$model=="EB" & data_fig$party==0], # opposition supp
           data_fig$lower95[data_fig$model=="EB" & data_fig$party==1]) # government supp
# 90 CIs
EB90u <- c(data_fig$upper90[data_fig$model=="EB" & data_fig$party==0], # opposition supp
           data_fig$upper90[data_fig$model=="EB" & data_fig$party==1]) # government supp
EB90l <- c(data_fig$lower90[data_fig$model=="EB" & data_fig$party==0], # opposition supp
           data_fig$lower90[data_fig$model=="EB" & data_fig$party==1]) # government supp

#### GM
# point estimates
GMpe <- c(data_fig$AME[data_fig$model=="GM" & data_fig$party==0], # opposition supp
          data_fig$AME[data_fig$model=="GM" & data_fig$party==1]) # government supp
# 95 CIs
GM95u <- c(data_fig$upper95[data_fig$model=="GM" & data_fig$party==0], # opposition supp
           data_fig$upper95[data_fig$model=="GM" & data_fig$party==1]) # government supp
GM95l <- c(data_fig$lower95[data_fig$model=="GM" & data_fig$party==0], # opposition supp
           data_fig$lower95[data_fig$model=="GM" & data_fig$party==1]) # government supp
# 90 CIs
GM90u <- c(data_fig$upper90[data_fig$model=="GM" & data_fig$party==0], # opposition supp
           data_fig$upper90[data_fig$model=="GM" & data_fig$party==1])
GM90l <- c(data_fig$lower90[data_fig$model=="GM" & data_fig$party==0], # opposition supp
           data_fig$lower90[data_fig$model=="GM" & data_fig$party==1]) # government supp

## Set common features across panels
ylim <- c(min(data_fig$lower95), max(data_fig$upper95)) # range y axis
xlim <- c(0.09, 0.12)
xticks <- c(0.0975, 0.1125) # ticks position
xlabels <- c("Opposition\nSupporters", "Government\nSupporters") # ticks labels
xseg <- c(0.095,0.100,0.110,0.115) # x_i segments
pts <- xseg # point estimates position
leglabel <- c("Lower Court", "Supreme Court") # legend labels

# These options are common for all plots, 
  # so set them up just once (as function or expression)
plots <- function(main, ylim, xlim) {
  plot(1, 1, xaxt = "n", yaxt = "n", 
       type = "n", ylab = "", xlab = "",
       main = main, 
       ylim = ylim, 
       xlim = xlim)
}

xaxis <- expression(
  axis(side = 1, at=xticks, las=1, labels = xlabels, 
       cex.axis=1.15, padj = 0.40)
)

yaxis <- expression(
  axis(side = 2, at = seq(-0.4,0.4,0.2), las = 1, labels = FALSE, 
       cex.axis = 1.15),
  text(x = 0.086, y = seq(-0.4, 0.4, 0.2), cex = 1.15, 
       labels = seq(-0.4, 0.4, 0.2), 
       srt = 90, 
       adj = 0.5, xpd = NA)
)

segs95 <- function(x0, y0, x1, y1) {
  segments(x0=x0, y0=y0, x1=x1, y1=y1, 
           lty = 1, lwd = 1.5)
}

segs90 <- function(x0, y0, x1, y1) {
  segments(x0=x0, y0=y0, x1=x1, y1=y1, 
           lty = 1, lwd = 3)
}

mypoints <- function(x, y) {
  points(x = x, y = y, 
         pch = c(21,24), cex = 1.5,
         col = "black", bg = c("white", "black"))
}

hline0 <- expression(abline(h = 0, col = "red", lty=2))

## Set up layout for panel
#png(file = "fig/png-figures/heterogeneous-court-ruling-effects.png", width = 7, height = 2.65, units = "in", res = 600)
#tiff(file = "fig/tiff-figures/heterogeneous-court-ruling-effects.tif", width = 7, height = 2.65, units = "in", res = 600)
pdf(file = "fig/heterogeneous-court-ruling-effects.pdf",
    width = 7, # The width of the plot in inches
    height = 2.65) # The height of the plot in inches
par(mar=c(1.9, 3.5, 2, 1), oma=c(1, 0, 0, 0)) # Set up margins by number of lines
layout(matrix(1:3, ncol=3), # 3-panel figure
       widths=c(0.355, 0.3225,0.3225)) # relative widths (1st panel wider due to ylab)

#### OLS
plots("OLS", ylim, xlim)
eval(xaxis)
eval(yaxis)
segs95(x0=xseg, y0=OLS95l,
       x1=xseg, y1=OLS95u)
segs90(x0=xseg, y0=OLS90l,
       x1=xseg, y1=OLS90u)
mypoints(x = pts, y = OLSpe)
eval(hline0)

title(ylab = "Effect of Court Decision", line = 2.2)

legend("topright", cex = 1, pt.cex = 1.2,
       legend=leglabel, pch = c(21,24), 
       col = "black", pt.bg = c("white", "black"))

# Entropy Balacing
par(mar=c(1.9, 2, 2, 1))

plots(main = "Entropy Balancing + WLS", ylim = ylim, xlim = xlim)
eval(xaxis)
eval(yaxis)
segs95(x0=xseg, y0=EB95l, x1=xseg, y1=EB95u)
segs90(x0=xseg,y0=EB90l, x1=xseg, y1=EB90u)
mypoints(x = pts, y = EBpe)
eval(hline0)

# Matching models
plots(main = "Genetic Matching + WLS", ylim = ylim, xlim = xlim)
eval(xaxis)
eval(yaxis)
segs95(x0=xseg, y0= GM95l, x1=xseg, y1= GM95u)
segs90(x0=xseg, y0= GM90l, x1=xseg, y1= GM90u)
mypoints(x= pts, y = GMpe)
eval(hline0)

# save plot
dev.off()

###########################################
# Appendix: Table C1.1 (full regression table for main results)

## Create full main regression table
  # Change name of categories of ordinal covariates in models m1 (OLS, lower) and m4 (OLS, supreme)
  # to match up with the other models
# Lower court
lower_cov <- as.data.frame(model.matrix(m1))
names(lower_cov)
new_names <- names(as.data.frame(model.matrix(m2))) # Names EB model
names(lower_cov) <- new_names
names(lower_cov)
# Supreme court
supreme_cov <- as.data.frame(model.matrix(m4))
names(supreme_cov)
new_names <- names(as.data.frame(model.matrix(m5))) # Names EB model
names(supreme_cov) <- new_names
names(supreme_cov)

# Now, rerun models 1 and 4
# Supreme court (m1)
lower_cov <- lower_cov[,-c(1,19:30)]
names(lower_cov)
lower_cov$trustbi <- rizzo1_lim$trustbi
lower_cov$prov <- rizzo1_lim$prov
lower_cov$city <- rizzo1_lim$city
lower_cov$date <- rizzo1_lim$date
names(lower_cov)
# Supreme court (m4)
supreme_cov <- supreme_cov[,-c(1,19:31)]
names(supreme_cov)
supreme_cov$trustbi <- rizzo2_lim$trustbi
supreme_cov$prov <- rizzo2_lim$prov
supreme_cov$city <- rizzo2_lim$city
supreme_cov$date <- rizzo2_lim$date
names(supreme_cov)

f <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
           SES_ordNot.bad + SES_ordGood + SES_ordVery.good + 
           subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save + 
           class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper + 
           religionCatolica + religionEvangelica + religionOtra + factor(prov)")
m1_new <- lm(f, data = lower_cov)
m4_new <- lm(f, data = supreme_cov)

# Check coefficients are the same
cbind("original" = summary(m1)$coef[c("Tr", "party2", "Tr:party2"),1], 
      "new" = summary(m1_new)$coef[c("Tr", "party2", "Tr:party2"),1])
cbind("original" = summary(m1)$coef[c("Tr", "party2", "Tr:party2"),2], 
      "new" = summary(m1_new)$coef[c("Tr", "party2", "Tr:party2"),2])
cbind("original" = summary(m4)$coef[c("Tr", "party2", "Tr:party2"),1], 
      "new" = summary(m4_new)$coef[c("Tr", "party2", "Tr:party2"),1])
cbind("original" = summary(m4)$coef[c("Tr", "party2", "Tr:party2"),2], 
      "new" = summary(m4_new)$coef[c("Tr", "party2", "Tr:party2"),2])
cor(summary(m1)$coef[,1], summary(m1_new)$coef[,1])
cor(summary(m1)$coef[,2], summary(m1_new)$coef[,2])
cor(summary(m4)$coef[,1], summary(m4_new)$coef[,1])
cor(summary(m4)$coef[,2], summary(m4_new)$coef[,2])

# All looks good!

# Finally, get SEs from the "new" regressions
names(lower_cov)
se1_new <- coeftest(m1_new, vcovCL(m1_new, cluster = ~ city + date, type = "HC1"))[,2]
se4_new <- coeftest(m4_new, vcovCL(m4_new, cluster = ~ city + date, type = "HC1"))[,2]

full_tab <- stargazer(m1_new, m2, m3, m4_new, m5, m6,
                      se=list(se1_new, se2, se3, se4_new, se5, se6),
                      title="Main Results - Full Table", align=TRUE,
                      dep.var.labels.include = FALSE, 
                      dep.var.caption = "",
                      label = "tab:full-main",
                      star.char = c("+", "*", "**", "***"),
                      star.cutoffs = c(.1, .05, .01, .001),
                      notes.append=FALSE, notes.align = "l", notes.label = "",
                      column.labels = c("\\textbf{Lower Court}",
                                        "\\textbf{Supreme Court}"),
                      column.separate = c(3, 3),
                      omit = c("prov"),
                      order = c(1,2,31,3:30,32),
                      covariate.labels = c("Court Ruling","Government Supporter", 
                                         "C. Ruling $\\times$ Gov. Supporter",
                                         "Age", "Female", "Education", 
                                         "SES (ref.: Bad/Very bad) & & & & & & \\\\ \\hspace{5mm} Not bad",
                                         "\\hspace{5mm} Good" , "\\hspace{5mm} Very good", 
                                         "Subj. Income (ref.: Insufficient and problems) & & & & & & \\\\ \\hspace{5mm} Insufficient", 
                                         "\\hspace{5mm} Just sufficient", 
                                         "\\hspace{5mm} Sufficient and save", 
                                         "Class (ref.: Lower) & & & & & & \\\\ \\hspace{5mm} Middle-lower", 
                                         "\\hspace{5mm} Middle", "\\hspace{5mm} Middle-upper", 
                                         "Religion (ref.: Agnostic/Atheist/None/NA) & & & & & & \\\\ \\hspace{5mm} Catholic", 
                                         "\\hspace{5mm} Evangelical", "\\hspace{5mm} Other"
                                         ),
                      omit.stat=c("f", "ser", "rsq"),
                      header = FALSE,
                      no.space = TRUE,
                      notes = c("\\small \\parbox[t]{1.1\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                      table.placement = "H",
                      add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                       c("sd(Trust)", Y_sd),
                                       c("\\midrule Province FE?",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}"))
          )
# Format table for publication
full_tab
full_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", full_tab, fixed=TRUE)
full_tab <- gsub("\\hline \\\\[-1.8ex] ", "", full_tab, fixed=TRUE)
full_tab <- gsub("\\hline ", "\\bottomrule", full_tab, fixed=TRUE)
full_tab <- gsub("[-1.8ex] ", "", full_tab, fixed=TRUE)
full_tab <- gsub("  \\label{tab:full-main} ", 
                 "\\tabcolsep=8pt  \\label{tab:full-main}  \\resizebox{0.9\\linewidth}{!}{%", full_tab, fixed=TRUE)
full_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", full_tab, fixed=TRUE)
full_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                 "\\begin{tabular}{l*{6}{d{1.3}}}", full_tab, fixed=TRUE)
full_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                 " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", full_tab, fixed=TRUE)
full_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
"& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", full_tab, fixed=TRUE)

sink("tab/main-results-full.tex")
cat(full_tab, sep="\n")
sink()


###########################################
# Appendix: Table C2.1 (Extended set of covariates)

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

## EXTENDED set of covariates and province fixed effects
  # Covariates that are potentially post-treatment 
f_OLS_ext <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + 
                        know + polint + TV_freq + newspaper_freq + internet_freq + factor(prov)")

## Lower court
m_OLS_ext_low <- lm(f_OLS_ext, data = rizzo1_ext)

## Supreme court
m_OLS_ext_sup <- lm(f_OLS_ext, data = rizzo2_ext)

### Save models for tables and figure
OLS_ext <- list("OLS_ext_lower" = m_OLS_ext_low, "OLS_ext_supreme" = m_OLS_ext_sup, 
                   "rizzo1_ext" = rizzo1_ext, "rizzo2_ext" = rizzo2_ext)
save(OLS_ext, file = "models/OLS-extended-covariates.RData")

###########
### Entropy balance + WLS models (binary outcome)
###########

## Lower Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion + know + polint + TV_freq + newspaper_freq + internet_freq"
  # Get covariate matrix
EB_ext_low <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo1_ext))
)

colnames(EB_ext_low)

  # Remove intercept
EB_ext_low <- EB_ext_low[, -1]

colnames(EB_ext_low)

  # Add in outcomes and missing variables
EB_ext_low <- cbind("trustbi" = rizzo1_ext$trustbi, 
                 "city" = rizzo1_ext$city, # City (clustered SEs and city FE)
                 "date" = rizzo1_ext$date, # Date of interview (clustered SEs)
                 "prov" = rizzo1_ext$prov, # Province (province FE)
                 EB_ext_low, # Covariate matrix
                 "trustord" = rizzo1_ext$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo1_ext$trust)  # scaled outcome (appendix analysis)
names(EB_ext_low)

  # Order observations to add entropy balance weights (controls first)
EB_ext_low <- rbind(EB_ext_low[EB_ext_low$Tr == 0,],EB_ext_low[EB_ext_low$Tr == 1,])

colnames(EB_ext_low)

# Compute entropy balance (EB) weights
out1_ext <- ebalance(Treatment = EB_ext_low$Tr, 
                     X = EB_ext_low[,6:26]) # include only covariates to balance on

# Add weights to (ordered) dataset
EB_ext_low$w <- c(out1_ext$w, # weights for control observations 
                  rep(1, nrow(EB_ext_low[EB_ext_low$Tr == 1,])))

# Check distribution of weights
hist(out1_ext$w, 100) # weights are well behaved

names(EB_ext_low)

# Formula for regressions with limited covariate dataset
names(EB_ext_low)
f_EB_ext <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                       paste0(paste0(names(EB_ext_low)[7:26], collapse = " + "), 
                              " + factor(prov)")))

# WLS with bias adjustment
m_EB_ext_low <- lm(f_EB_ext, data = EB_ext_low, weights = w)


## Supreme Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion + know + polint + TV_freq + newspaper_freq + internet_freq"
  # Get covariate matrix
EB_ext_sup <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_ext))
)

colnames(EB_ext_sup)

  # Remove intercept
EB_ext_sup <- EB_ext_sup[, -1]

colnames(EB_ext_sup)

  # Add in outcomes and missing variables
EB_ext_sup <- cbind("trustbi" = rizzo2_ext$trustbi, 
                 "city" = rizzo2_ext$city, # City (clustered SEs and city FE)
                 "date" = rizzo2_ext$date, # Date of interview (clustered SEs)
                 "prov" = rizzo2_ext$prov, # Province (province FE)
                 EB_ext_sup, # Covariate matrix
                 "trustord" = rizzo2_ext$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo2_ext$trust)  # scaled outcome (appendix analysis)
names(EB_ext_sup)

  # Order observations to add entropy balance weights (controls first)
EB_ext_sup <- rbind(EB_ext_sup[EB_ext_sup$Tr == 0,],EB_ext_sup[EB_ext_sup$Tr == 1,])

colnames(EB_ext_sup)

# Compute entropy balance (EB) weights
out2_ext <- ebalance(Treatment = EB_ext_sup$Tr, 
                     X = EB_ext_sup[,6:26]) # include only covariates to balance on

# Check distribution of weights
hist(out2_ext$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_ext_sup$w <- c(out2_ext$w, # weights for control observations 
                  rep(1, nrow(EB_ext_sup[EB_ext_sup$Tr == 1,])))

# WLS with bias adjustment
m_EB_ext_sup <- lm(f_EB_ext, data = EB_ext_sup, weights = w)


### Save models for tables and figure
EB_ext <- list("EB_ext_lower" = m_EB_ext_low, "EB_ext_supreme" = m_EB_ext_sup, 
                "EB_ext_low" = EB_ext_low, "EB_ext_sup" = EB_ext_sup)
save(EB_ext, file = "models/EB-extended-covariates.RData")


###########
### Genetic matching + WLS models (binary outcome)
###########

## Lower Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out1_ext <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + 
                     know + polint + TV_freq + newspaper_freq + internet_freq
                   + factor(prov), 
                   family = binomial(link = "probit"), data = rizzo1_ext)
e <- fitted(ps.out1_ext, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match1_ext <- data.frame(model.matrix(ps.out1_ext))
names(match1_ext)
  # Remove intercept and prov
match1_ext <- match1_ext[,-c(1,23:33)]
names(match1_ext)
  # Add linearized estimated propensity scores
match1_ext$l <- l
names(match1_ext)
  # Add in other variables
match1_ext <- cbind("trustbi" = rizzo1_ext$trustbi, 
                    "Tr" = rizzo1_ext$Tr, 
                    "city" = rizzo1_ext$city, # City (clustered SEs and city FE)
                    "date" = rizzo1_ext$date, # Date of interview (clustered SEs)
                    "prov" = rizzo1_ext$prov, # Province (province FE)
                    match1_ext, 
                    "trustord" = rizzo1_ext$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo1_ext$trust)  # scaled outcome (appendix analysis)
names(match1_ext)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 50 minutes
  # Solution Found Generation 44
  # Number of Generations Run 95
set.seed(1)
gm.out1_ext <-	GenMatch(Tr = match1_ext$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match1_ext[, c(6:27)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out1_ext, file = "genetic-matching-output/gen-match-output-lower-ext.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-lower-ext.RData")

# Use Match() to obtain dataset of matched observations
mout1_ext <- Match(Y = match1_ext$trustbi,
                  Tr = match1_ext$Tr, 
                  # Include only covariates (and linearized estimated propensity scores)
                  X = match1_ext[, c(6:27)], 
                  Weight.matrix = gm.out1_ext,
                  BiasAdjust = T,
                  ties=T, 
                  replace=T)

# Vectors of matched control and treated observations
sel <- c(mout1_ext$index.treated, mout1_ext$index.control)
# Create dataset of matches
GM_ext_low <- match1_ext[sel,]
# Add weights
GM_ext_low$w <- c(mout1_ext$weights, mout1_ext$weights)

##  GM + WLS with bias adjustment
names(GM_ext_low)

# Formula for regressions with limited covariate dataset
f_GM_ext <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                                paste0(paste0(names(GM_ext_low)[7:26], collapse = " + "), 
                                     " + factor(prov)")))

m_GM_ext_low <- lm(f_GM_ext, data = GM_ext_low, weights = w)


## Supreme Court
# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out2_ext <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + 
                     know + polint + TV_freq + newspaper_freq + internet_freq
                   + factor(prov), 
                   family = binomial(link = "probit"), data = rizzo2_ext)
e <- fitted(ps.out2_ext, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match2_ext <- data.frame(model.matrix(ps.out2_ext))
names(match2_ext)
  # Remove intercept and prov
match2_ext <- match2_ext[,-c(1,23:34)]
names(match2_ext)
  # Add linearized estimated propensity scores
match2_ext$l <- l
names(match2_ext)
  # Add in other variables
match2_ext <- cbind("trustbi" = rizzo2_ext$trustbi, 
                    "Tr" = rizzo2_ext$Tr, 
                    "city" = rizzo2_ext$city, # City (clustered SEs and city FE)
                    "date" = rizzo2_ext$date, # Date of interview (clustered SEs)
                    "prov" = rizzo2_ext$prov, # Province (province FE)
                    match2_ext, 
                    "trustord" = rizzo2_ext$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo2_ext$trust)  # scaled outcome (appendix analysis)
names(match2_ext)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 60 minutes
  # Solution Found Generation 60
  # Number of Generations Run 111
set.seed(1)
gm.out2_ext <-	GenMatch(Tr = match2_ext$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match2_ext[, c(6:27)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out2_ext, file = "genetic-matching-output/gen-match-output-supreme-ext.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-supreme-ext.RData")

# Use Match() to obtain dataset of matched observations
mout2_ext <- Match(Y = match2_ext$trustbi,
                   Tr = match2_ext$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match2_ext[, c(6:27)], 
                   Weight.matrix = gm.out2_ext,
                   BiasAdjust = T,
                   ties=T,
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_ext$index.treated, mout2_ext$index.control)
# Create dataset of matches
GM_ext_sup <- match2_ext[sel,]
# Add weights
GM_ext_sup$w <- c(mout2_ext$weights, mout2_ext$weights)

##  GM + WLS with bias adjustment
m_GM_ext_sup <- lm(f_GM_ext, data = GM_ext_sup, weights = w)

### Save models for tables and figure
GM_ext <- list("GM_ext_lower" = m_GM_ext_low, "GM_ext_supreme" = m_GM_ext_sup, 
               "GM_ext_low" = GM_ext_low, "GM_ext_sup" = GM_ext_sup)
save(GM_ext, file = "models/GM-extended-covariates.RData")


###########################################
# Appendix: Table C2.1

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call OLS models
load("models/OLS-extended-covariates.RData")
# Call entropy balancing binary models
load("models/EB-extended-covariates.RData")
# Call genetic matching models
load("models/GM-extended-covariates.RData")

names(OLS_ext)
names(EB_ext)
names(GM_ext)

# Lower Court models (extended set of covariates)
m1_ext <- OLS_ext[["OLS_ext_lower"]] # OLS model

m2_ext <- EB_ext[["EB_ext_lower"]] # EB model
EB_ext_low <- EB_ext[["EB_ext_low"]] # EB dataset

m3_ext <- GM_ext[["GM_ext_lower"]] # GM model
GM_ext_low <- GM_ext[["GM_ext_low"]] # GM dataset

# Supreme Court models (extended set of covariates)
m4_ext <- OLS_ext[["OLS_ext_supreme"]] # OLS model

m5_ext <- EB_ext[["EB_ext_supreme"]] # EB model
EB_ext_sup <- EB_ext[["EB_ext_sup"]] # EB dataset

m6_ext <- GM_ext[["GM_ext_supreme"]] # GM model
GM_ext_sup <- GM_ext[["GM_ext_sup"]] # GM dataset

## Compute cluster-robust standard errors
se1_ext <- coeftest(m1_ext, vcovCL(m1_ext, cluster = ~ city + date, type = "HC1"))[,2]
se2_ext <- coeftest(m2_ext, vcovCL(m2_ext, cluster = ~ city + date, type = "HC1"))[,2]
se3_ext <- coeftest(m3_ext, vcovCL(m3_ext, cluster = ~ city + date, type = "HC1"))[,2]
se4_ext <- coeftest(m4_ext, vcovCL(m4_ext, cluster = ~ city + date, type = "HC1"))[,2]
se5_ext <- coeftest(m5_ext, vcovCL(m5_ext, cluster = ~ city + date, type = "HC1"))[,2]
se6_ext <- coeftest(m6_ext, vcovCL(m6_ext, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar_ext <- round(c(mean(m1_ext$resid + m1_ext$fitted.values), 
                 mean(m2_ext$resid + m2_ext$fitted.values),
                 mean(m3_ext$resid + m3_ext$fitted.values),
                 mean(m4_ext$resid + m4_ext$fitted.values),
                 mean(m5_ext$resid + m5_ext$fitted.values),
                 mean(m6_ext$resid + m6_ext$fitted.values)),3)
Y_sd_ext <- round(c(sd(m1_ext$resid + m1_ext$fitted.values), 
                sd(m2_ext$resid + m2_ext$fitted.values),
                sd(m3_ext$resid + m3_ext$fitted.values),
                sd(m4_ext$resid + m4_ext$fitted.values),
                sd(m5_ext$resid + m5_ext$fitted.values),
                sd(m6_ext$resid + m6_ext$fitted.values)),3)


## Create table
  # Change name of categories of ordinal covariates in models m1 (OLS, lower) and m4 (OLS, supreme)
  # to match up with the other models
  # Lower court
lower_cov_ext <- as.data.frame(model.matrix(m1_ext))
names(lower_cov_ext)
new_names_ext <- names(as.data.frame(model.matrix(m2_ext))) # Names EB model
names(lower_cov_ext) <- new_names_ext
names(lower_cov_ext)
# Supreme court
supreme_cov_ext <- as.data.frame(model.matrix(m4_ext))
names(supreme_cov_ext)
new_names_ext <- names(as.data.frame(model.matrix(m5_ext))) # Names EB model
names(supreme_cov_ext) <- new_names_ext
names(supreme_cov_ext)

# Now, rerun models 1 and 4
# Supreme court (m1)
lower_cov_ext <- lower_cov_ext[,-c(1,24:36)]
names(lower_cov_ext)
lower_cov_ext$trustbi <- rizzo1_ext$trustbi
lower_cov_ext$prov <- rizzo1_ext$prov
lower_cov_ext$city <- rizzo1_ext$city
lower_cov_ext$date <- rizzo1_ext$date
names(lower_cov_ext)
# Supreme court (m4)
names(supreme_cov_ext)
supreme_cov_ext <- supreme_cov_ext[,-c(1,24:36)]
names(supreme_cov_ext)
supreme_cov_ext$trustbi <- rizzo2_ext$trustbi
supreme_cov_ext$prov <- rizzo2_ext$prov
supreme_cov_ext$city <- rizzo2_ext$city
supreme_cov_ext$date <- rizzo2_ext$date
names(supreme_cov_ext)

f <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
           SES_ordNot.bad + SES_ordGood + SES_ordVery.good + 
           subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save + 
           class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper + 
           religionCatolica + religionEvangelica + religionOtra + 
           know + polint + TV_freq + newspaper_freq + internet_freq + factor(prov)")
m1_new_ext <- lm(f, data = lower_cov_ext)
m4_new_ext <- lm(f, data = supreme_cov_ext)

# Check coefficients/SEs are the same
cbind("original" = summary(m1_ext)$coef[c("Tr", "party2", "Tr:party2"),1], 
      "new" = summary(m1_new_ext)$coef[c("Tr", "party2", "Tr:party2"),1])
cbind("original" = summary(m1_ext)$coef[c("Tr", "party2", "Tr:party2"),2], 
      "new" = summary(m1_new_ext)$coef[c("Tr", "party2", "Tr:party2"),2])
cbind("original" = summary(m4_ext)$coef[c("Tr", "party2", "Tr:party2"),1], 
      "new" = summary(m4_new_ext)$coef[c("Tr", "party2", "Tr:party2"),1])
cbind("original" = summary(m4_ext)$coef[c("Tr", "party2", "Tr:party2"),2], 
      "new" = summary(m4_new_ext)$coef[c("Tr", "party2", "Tr:party2"),2])

cor(summary(m1_ext)$coef[,1], summary(m1_new_ext)$coef[,1])
cor(summary(m1_ext)$coef[,2], summary(m1_new_ext)$coef[,2])
cor(summary(m4_ext)$coef[,1], summary(m4_new_ext)$coef[,1])
cor(summary(m4_ext)$coef[,2], summary(m4_new_ext)$coef[,2])

# All looks good

# get SEs from the new regressions
names(lower_cov_ext)
se1_new_ext <- coeftest(m1_new_ext, vcovCL(m1_new_ext, cluster = ~ city + date, type = "HC1"))[,2]
se4_new_ext <- coeftest(m4_new_ext, vcovCL(m4_new_ext, cluster = ~ city + date, type = "HC1"))[,2]

full_tab_ext <- stargazer(m1_new_ext, m2_ext, m3_ext, m4_new_ext, m5_ext, m6_ext,
                      se=list(se1_new_ext, se2_ext, se3_ext, se4_new_ext, se5_ext, se6_ext),
                      title="Extended Set of Covariates", align=TRUE,
                      dep.var.labels.include = FALSE, 
                      dep.var.caption = "",
                      label = "tab:ext",
                      column.labels = c("\\textbf{Lower Court}",
                                        "\\textbf{Supreme Court}"),
                      column.separate = c(3, 3),
                      omit = c("prov"),
                      order = c(1,2, 36, 3:35),
                      covariate.labels = c("Court Ruling","Government Supporter", 
                                           "C. Ruling $\\times$ Gov. Supporter",
                                           "Age", "Female", "Education", 
                                           "SES (ref.: Bad/Very bad) & & & & & & \\\\ \\hspace{5mm} Not bad",
                                           "\\hspace{5mm} Good" , "\\hspace{5mm} Very good", 
                                           "Subj. Income (ref.: Insufficient and problems) & & & & & & \\\\ \\hspace{5mm} Insufficient", 
                                           "\\hspace{5mm} Just sufficient", 
                                           "\\hspace{5mm} Sufficient and save", 
                                           "Class (ref.: Lower) & & & & & & \\\\ \\hspace{5mm} Middle-lower", 
                                           "\\hspace{5mm} Middle", "\\hspace{5mm} Middle-upper", 
                                           "Religion (ref.: Agnostic/Atheist/None/NA) & & & & & & \\\\ \\hspace{5mm} Catholic", 
                                           "\\hspace{5mm} Evangelical", "\\hspace{5mm} Other", 
                                           "Political Knowledge", "Political Interest", "TV Frequency", "Newspaper Frequency", "Internet Use"
                                           ),
                      star.char = c("+", "*", "**", "***"),
                      star.cutoffs = c(.1, .05, .01, .001),
                      notes.append=FALSE, notes.align = "l", notes.label = "",
                      omit.stat=c("f", "ser", "rsq"),
                      header = FALSE,
                      no.space = TRUE,
                      notes = c("\\small \\parbox[t]{1.1\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                      table.placement = "H",
                      add.lines = list(c("\\midrule Mean(Trust)", Y_bar_ext),
                                       c("sd(Trust)", Y_sd_ext),
                                       c("\\midrule Controls?",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}"),
                                       c("Province FE?",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}"))
                      )
# Format table for publication
full_tab_ext
full_tab_ext <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub("\\hline \\\\[-1.8ex] ", "", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub("\\hline ", "\\bottomrule", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub("[-1.8ex] ", "", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub("  \\label{tab:ext} ", 
                 "\\tabcolsep=8pt  \\label{tab:ext}  \\resizebox{0.8\\linewidth}{!}{%", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub("\\end{tabular} ", "\\end{tabular} }", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                 "\\begin{tabular}{l*{6}{d{1.3}}}", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                 " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", full_tab_ext, fixed=TRUE)
full_tab_ext <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                 "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", full_tab_ext, fixed=TRUE)

sink("tab/extended-covariates.tex")
cat(full_tab_ext, sep="\n")
sink()


######################################
############# Moderators ############# 
#### Main text results: figure 6
#### Appendix: figures D1.1 and D2.1
######################################

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

###########################################
# Main text: Figure 6 (Newspaper Frequency and Political Interest)

# Call GM dataset using extended set of covariates
load("models/GM-extended-covariates.RData")
names(GM_ext)

# Supreme Court models (extended set of covariates)
GM_ext_sup <- GM_ext[["GM_ext_sup"]] # GM dataset

GM_ext_sup$newspaper_freq_log <- log(GM_ext_sup$newspaper_freq+1)

f_newspaper <- as.formula("trustbi ~ Tr*party2*newspaper_freq_log + age + female + education + 
          SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
          subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save + 
          class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
          religionCatolica + religionEvangelica + religionOtra +
          know + polint + TV_freq + internet_freq + 
          factor(prov)")

# Fit model with bias adjustment
m_newspaper <- lm(f_newspaper, weights = w, data = GM_ext_sup)

## variance-covariance matrix
  ## The date and city clustered vcov produces too many NA values when computing the 
    # standard errors for the marginal effects
    # So, cluster by date only (instead of date and city)
vcov_newspaper <- vcovCL(m_newspaper, cluster = ~ date, type = "HC1")

fig_newspaper <- cbind(as.data.frame(avg_comparisons(m_newspaper, variable = "Tr", by = c("newspaper_freq_log", "party2"), 
                                                     vcov = vcov_newspaper))[,3:11], 
                       as.data.frame(avg_comparisons(m_newspaper, variable = "Tr", by = c("newspaper_freq_log", "party2"), 
                                                     vcov = vcov_newspaper, conf_level = 0.9))[,10:11],
                       model = "GM")
names(fig_newspaper)
names(fig_newspaper)[1] <- "moderator"
names(fig_newspaper)
names(fig_newspaper)[10:11] <- c("conf.low90", "conf.high90")
names(fig_newspaper)
fig_newspaper$mod <- "newspaper"
fig_newspaper


f_polint <- as.formula("trustbi ~ Tr*party2*polint + age + female + education + 
          SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
          subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save + 
          class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
          religionCatolica + religionEvangelica + religionOtra +
          know + TV_freq + newspaper_freq + internet_freq + 
          factor(prov)")

m_polint <- lm(f_polint, weights = w, data = GM_ext_sup)

## variance-covariance matrix
vcov_polint <- vcovCL(m_polint, cluster = ~ city + date, type = "HC1")

fig_polint <- cbind(as.data.frame(avg_comparisons(m_polint, variable = "Tr", by = c("polint", "party2"), 
                                    vcov = vcov_polint))[,3:11], 
                          as.data.frame(avg_comparisons(m_polint, variable = "Tr", by = c("polint", "party2"), 
                                    vcov = vcov_polint, conf_level = 0.9))[,10:11],
                          model = "GM")

names(fig_polint)
names(fig_polint)[1] <- "moderator"
names(fig_polint)
names(fig_polint)[10:11] <- c("conf.low90", "conf.high90")
names(fig_polint)
fig_polint$mod <- "polint"
fig_polint

# Stack data
fig_moderator <- rbind(fig_newspaper[fig_newspaper$model == "GM",], 
                       fig_polint[fig_polint$model == "GM",])

head(fig_moderator)

ran_x <- range(fig_moderator$moderator[fig_moderator$mod == "newspaper"])

# Plot media exposure moderators (continuous)
#png(file = "fig/png-figures/newspaper-polint-moderator.png", width = 7.5, height = 3.5, units = "in", res = 600)
#tiff(file = "fig/tiff-figures/newspaper-polint-moderator.tif", width = 7.5, height = 3.5, units = "in", res = 600)
pdf(file = "fig/newspaper-polint-moderator.pdf",
    width = 7.5, # width of plot (inches)
    height = 3.5) # height of plot (inches)
par(mar=c(3, 3.5, 1, 1), oma=c(1, 0, 0, 0.5)) # Set up margins by number of lines
layout(matrix(1:2, ncol=2), # 2-panel figure
       widths=c(0.525, 0.475)) # relative widths (1st panel wider bc of ylab)

### Newspaper
plot(1, 1, type = "n", yaxt = "n", #xaxt = "n", 
     ylim = c(-1.06,1.06),
     xlim = ran_x,
     ylab = "", main = "",
     xlab = "")

axis(side = 2, at = seq(-1,1,0.5), las = 1, labels = FALSE, 
     cex.axis = 0.9)
text(x = -0.25, y = seq(-1,1,0.5), cex = 0.9, 
     labels = seq(-1,1,0.5), 
     srt = 90, 
     adj = 0.5, xpd = NA)
mtext("Effect of Supreme Court Ruling", side = 2, line = 2.25, cex = 1.1)

mtext("log(# Days Read News in a Newspaper)", side = 1, line = 2.25, cex = 1)

# Opposition Supporters
# Estimates
lines(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0], 
      fig_moderator$estimate[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0], 
      lty = 1, lwd = 2.5)
# 95% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0], 
          rev(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0])), 
        c(fig_moderator$conf.high[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0], 
          rev(fig_moderator$conf.low[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
# 90% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0], 
          rev(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0])), 
        c(fig_moderator$conf.high90[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0], 
          rev(fig_moderator$conf.low90[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 0])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
# Government supp
# Estimates
lines(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1], 
      fig_moderator$estimate[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1], 
      lty = 3, lwd = 2)
# 95% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1], 
          rev(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1])), 
        c(fig_moderator$conf.high[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1], 
          rev(fig_moderator$conf.low[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
# 90% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1], 
          rev(fig_moderator$moderator[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1])), 
        c(fig_moderator$conf.high90[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1], 
          rev(fig_moderator$conf.low90[fig_moderator$mod == "newspaper" & fig_moderator$party2 == 1])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
abline(h = 0, col = "red", lty = 2, lwd = 2)

legend("topleft", bty = "n",
       legend = c("Opposition Supp.", "Government Supp."),
       lty = c(1,3), lwd = 2.5, cex = 0.95)

### Political interest
par(mar=c(3, 2, 1, 1))

plot(1, 1, type = "n", xaxt = "n", yaxt = "n",
     ylim = c(-1, 1),
     xlim = c(0,3),
     ylab = "", main = "",
     xlab = "")

axis(side = 2, at = seq(-1,1,0.5), las = 1, labels = FALSE, 
       cex.axis = 0.9)
text(x = -0.375, y = seq(-1, 1, 0.5), cex = 0.9, 
       labels = round(seq(-1,1,0.5),1), 
       srt = 90, 
       adj = 0.5, xpd = NA)
axis (side = 1, at = c(0,1,2,3), tck = -0.02, cex.axis = 0.8,
      labels = c("Not at all\ninterested", "A little\ninterested", "Fairly\ninterested", "Very\ninterested"))
mtext("Political Interest", side = 1, line = 2.25, cex = 1)

# Opposition Supporters
# Estimates
lines(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 0], 
      fig_moderator$estimate[fig_moderator$mod == "polint" & fig_moderator$party2 == 0], 
      lty = 1, lwd = 2.5)
# 95% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 0], 
          rev(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 0])), 
        c(fig_moderator$conf.high[fig_moderator$mod == "polint" & fig_moderator$party2 == 0], 
          rev(fig_moderator$conf.low[fig_moderator$mod == "polint" & fig_moderator$party2 == 0])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
# 90% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 0], 
          rev(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 0])), 
        c(fig_moderator$conf.high90[fig_moderator$mod == "polint" & fig_moderator$party2 == 0], 
          rev(fig_moderator$conf.low90[fig_moderator$mod == "polint" & fig_moderator$party2 == 0])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
# Government supp
# Estimates
lines(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 1], 
      fig_moderator$estimate[fig_moderator$mod == "polint" & fig_moderator$party2 == 1], 
      lty = 3, lwd = 2)
# 95% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 1], 
          rev(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 1])), 
        c(fig_moderator$conf.high[fig_moderator$mod == "polint" & fig_moderator$party2 == 1], 
          rev(fig_moderator$conf.low[fig_moderator$mod == "polint" & fig_moderator$party2 == 1])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
# 90% CIs
polygon(c(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 1], 
          rev(fig_moderator$moderator[fig_moderator$mod == "polint" & fig_moderator$party2 == 1])), 
        c(fig_moderator$conf.high90[fig_moderator$mod == "polint" & fig_moderator$party2 == 1], 
          rev(fig_moderator$conf.low90[fig_moderator$mod == "polint" & fig_moderator$party2 == 1])), 
        col = rgb(0.7, 0.7, 0.7, alpha = 0.3), border = NA, 
        lty = 1)
abline(h = 0, col = "red", lty = 2, lwd = 2)


dev.off()


###########################################
# Appendix: Figure D2.1 (Binary Newspaper Frequency and Political Interest)

## Newspaper binary
GM_ext_sup$newspaper_binary <- ifelse(GM_ext_sup$newspaper_freq_log > median(GM_ext_sup$newspaper_freq_log), 1, 0)

f_newspaper_binary <- as.formula("trustbi ~ Tr*party2*newspaper_binary + age + female + education + 
          SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
          subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save + 
          class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
          religionCatolica + religionEvangelica + religionOtra +
          know + polint + TV_freq + internet_freq + 
          factor(prov)")

m_newspaper_binary <- lm(f_newspaper_binary, weights = w, data = GM_ext_sup)

## variance-covariance matrix
vcov_newspaper_binary <- vcovCL(m_newspaper_binary, cluster = ~ city + date, type = "HC1")

## First differences
fig_newspaper_binary <- cbind(as.data.frame(avg_comparisons(m_newspaper_binary, variable = "Tr", by = c("newspaper_binary", "party2"), 
                                                                  vcov = vcov_newspaper_binary))[,3:11], 
                                    as.data.frame(avg_comparisons(m_newspaper_binary, variable = "Tr", by = c("newspaper_binary", "party2"), 
                                                                  vcov = vcov_newspaper_binary, conf_level = 0.9))[,10:11],
                                    model = "GM")
fig_newspaper_binary
names(fig_newspaper_binary)
names(fig_newspaper_binary)[1] <- "moderator"
names(fig_newspaper_binary)[10:11] <- c("conf.low90", "conf.high90")
names(fig_newspaper_binary)
fig_newspaper_binary$mod <- "newspaper"
names(fig_newspaper_binary)
fig_newspaper_binary

## Polint binary
GM_ext_sup$polint_binary <- ifelse(GM_ext_sup$polint %in% c(2,3), 1, 0)

f_polint_binary <- as.formula("trustbi ~ Tr*party2*polint_binary + age + female + education + 
          SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
          subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save + 
          class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
          religionCatolica + religionEvangelica + religionOtra +
          know + TV_freq + newspaper_freq + internet_freq + 
          factor(prov)")

m_polint_binary <- lm(f_polint_binary, weights = w, data = GM_ext_sup)

## variance-covariance matrix
vcov_polint_binary <- vcovCL(m_polint_binary, cluster = ~ city + date, type = "HC1")

## First differences
fig_polint_binary <- cbind(as.data.frame(avg_comparisons(m_polint_binary, variable = "Tr", by = c("polint_binary", "party2"), 
                                                            vcov = vcov_polint_binary))[,3:11], 
                              as.data.frame(avg_comparisons(m_polint_binary, variable = "Tr", by = c("polint_binary", "party2"), 
                                                            vcov = vcov_polint_binary, conf_level = 0.9))[,10:11],
                              model = "GM")
fig_polint_binary
names(fig_polint_binary)
names(fig_polint_binary)[1] <- "moderator"
names(fig_polint_binary)[10:11] <- c("conf.low90", "conf.high90")
names(fig_polint_binary)
fig_polint_binary$mod <- "polint"
names(fig_polint_binary)
fig_polint_binary

fig_moderator_binary <- rbind(fig_newspaper_binary[fig_newspaper_binary$model == "GM",], 
                       fig_polint_binary[fig_polint_binary$model == "GM",])

head(fig_moderator_binary,8)


# Prepare parameters for figure
xlim <- c(0.09, 0.12)
xticks <- c(0.0975, 0.1125) # ticks position
xlabels_newspaper <- c(expression(""<= "median"), "> median") # ticks labels
xlabels_polint <- c("Not at all/\nA little", "Fairly/\nVery") # ticks labels
xseg <- c(0.095,0.100,0.110,0.115) # x_i segments
pts <- xseg # point estimates position
leglabel <- c("Opposition Supp.", "Government Supp.") # legend labels

# Plot media exposure moderators (binary)
#png(file = "fig/png-figures/newspaper-polint-moderator-binary.png", width = 7.5, height = 4.25, units = "in", res = 600)
#tiff(file = "fig/tiff-figures/newspaper-polint-moderator-binary.tif", width = 7.5, height = 4.25, units = "in", res = 600)
pdf(file = "fig/newspaper-polint-moderator-binary.pdf", 
    width = 7, # width of plot (inches)
    height = 4.25) # height of plot (inches)
par(mar=c(3, 3.5, 1, 1), oma=c(1, 0, 0, 0.5)) # Set up margins by number of lines
layout(matrix(1:2, ncol=2), # 2-panel figure
       widths=c(0.525, 0.475)) # relative widths (1st panel wider bc of ylab)
### Newspaper
plot(1, 1, type = "n", xaxt = "n", yaxt = "n", 
     ylim = c(min(fig_moderator_binary$conf.low[fig_moderator_binary$mod == "newspaper"]), 
              max(fig_moderator_binary$conf.high[fig_moderator_binary$mod == "newspaper"])+0.01), 
     xlim = xlim,
     ylab = "", main = "",
     xlab = "")

axis(side = 1, at = xticks, tck = -0.02, cex.axis = 1, labels = xlabels_newspaper, 
      padj = -1)
axis(side = 2, at = seq(-0.8,0.6,0.2), tck = -0.05, las = 1, labels = FALSE, 
     cex.axis = 1)
text(x = 0.085, y = seq(-0.8,0.6,0.2), cex = 1, 
     labels = seq(-0.8,0.6,0.2), 
     srt = 90, 
     adj = 0.5, xpd = NA)
mtext("Effect of Supreme Court Ruling", side = 2, line = 2.25, cex = 1.1)

mtext("# Days Read Newspaper", side = 1, line = 2.25, cex = 1.1)

# Opposition Supporters
# Estimates
# 90% CIs
segments(x0=xseg, x1=xseg, 
         y0=fig_moderator_binary$conf.low90[fig_moderator_binary$mod == "newspaper"], 
         y1=fig_moderator_binary$conf.high90[fig_moderator_binary$mod == "newspaper"], 
         lwd = 3, col = c("darkgray","black"))
# 95% CIs
segments(x0=xseg, x1=xseg, 
         y0=fig_moderator_binary$conf.low[fig_moderator_binary$mod == "newspaper"], 
         y1=fig_moderator_binary$conf.high[fig_moderator_binary$mod == "newspaper"], 
         lwd = 2, col = c("darkgray","black"))
points(xseg, 
       fig_moderator_binary$estimate[fig_moderator_binary$mod == "newspaper"], 
       pch = c(21,24), cex = 2,
       col = c("darkgray","black"), 
       bg = c("darkgray", "black"))


abline(h = 0, col = "red", lty = 2, lwd = 2)

legend("topleft", bty = "n", cex = 0.95,
       legend = c("Opposition Supp.", "Government Supp."),
       pch = c(21,24), pt.bg = c("darkgray", "black"),  col = c("darkgray","black"))

### Political interest
par(mar=c(3, 2, 1, 1))

plot(1, 1, type = "n", xaxt = "n", 
     ylim = c(min(fig_moderator_binary$conf.low[fig_moderator_binary$mod == "polint"]), 
              max(fig_moderator_binary$conf.high[fig_moderator_binary$mod == "polint"])+0.01), 
     xlim = xlim,
     ylab = "", main = "",
     xlab = "")

axis (side = 1, at = xticks, tck = -0.02, cex.axis = 1, labels = xlabels_polint
      , padj = 0.2
      )
mtext("Political Interest", side = 1, line = 2.25, cex = 1.1)

# Estimates
# 90% CIs
segments(x0=xseg, x1=xseg, 
         y0=fig_moderator_binary$conf.low90[fig_moderator_binary$mod == "polint"], 
         y1=fig_moderator_binary$conf.high90[fig_moderator_binary$mod == "polint"], 
         lwd = 3, col = c("darkgray","black"))
# 95% CIs
segments(x0=xseg, x1=xseg, 
         y0=fig_moderator_binary$conf.low[fig_moderator_binary$mod == "polint"], 
         y1=fig_moderator_binary$conf.high[fig_moderator_binary$mod == "polint"], 
         lwd = 2, col = c("darkgray","black"))
points(xseg, 
       fig_moderator_binary$estimate[fig_moderator_binary$mod == "polint"], 
       pch = c(21,24), cex = 2,
       col = c("darkgray","black"), 
       bg = c("darkgray", "black"))

abline(h = 0, col = "red", lty = 2, lwd = 2)

dev.off()

###########################################
# Appendix: Figure D1.1 (Partisanship Strength)

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))


## Remove NAs
sel_strongsup <- !is.na(rizzo2_lim$strongsup)
rizzo2_strongsup <- rizzo2_lim[sel_strongsup,]

## Formula for analysis for strong supporters
f_OLS_strongsup <- as.formula("trustbi ~ Tr*party2*factor(strongsup) + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(prov)")

## Supreme court
m_OLS_strongsup <- lm(f_OLS_strongsup, data = rizzo2_strongsup)

### Save models for tables and figure
OLS_strongsup_model <- list("OLS_strong_supporters" = m_OLS_strongsup, 
                      "rizzo2_strongsup" = rizzo2_strongsup)
save(OLS_strongsup_model, file = "models/OLS-strong-supporters.RData")

###########
### Entropy balance + WLS models (binary outcome)
###########

## Supreme Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + factor(strongsup) + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_strongsup <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_strongsup))
)

colnames(EB_strongsup)

  # Remove intercept
EB_strongsup <- EB_strongsup[, -1]

colnames(EB_strongsup)

  # Add in outcomes and missing variables
EB_strongsup <- cbind("trustbi" = rizzo2_strongsup$trustbi, 
                 "city" = rizzo2_strongsup$city, # City (clustered SEs and city FE)
                 "date" = rizzo2_strongsup$date, # Date of interview (clustered SEs)
                 "prov" = rizzo2_strongsup$prov, # Province (province FE)
                 EB_strongsup, # Covariate matrix
                 "trustord" = rizzo2_strongsup$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo2_strongsup$trust)  # scaled outcome (appendix analysis)
names(EB_strongsup)

  # Order observations to add entropy balance weights (controls first)
EB_strongsup <- rbind(EB_strongsup[EB_strongsup$Tr == 0,], 
                      EB_strongsup[EB_strongsup$Tr == 1,])

colnames(EB_strongsup)

# Compute entropy balance (EB) weights
out2_strongsup <- ebalance(Treatment = EB_strongsup$Tr, 
                     X = EB_strongsup[,6:23]) # include only covariates to balance on

# Check distribution of weights
hist(out2_strongsup$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_strongsup$w <- c(out2_strongsup$w, # weights for control observations 
                  rep(1, nrow(EB_strongsup[EB_strongsup$Tr == 1,])))

# Formula for regressions with strong-supporters covariate dataset
names(EB_strongsup)
f_EB_strongsup <- as.formula(paste0("trustbi ~ Tr*party2*(factor.strongsup.1 + factor.strongsup.2) + ", 
                       paste0(paste0(names(EB_strongsup)[9:23], collapse = " + "), 
                              " + factor(prov)")))

# WLS with bias adjustment
m_EB_strongsup <- lm(f_EB_strongsup, data = EB_strongsup, weights = w)

### Save models for tables and figure
EB_strongsup_model <- list("EB_strong_supporters" = m_EB_strongsup, 
                     "EB_strongsup" = EB_strongsup)
save(EB_strongsup_model, file = "models/EB-strong-supporters.RData")

###########
### Genetic matching + WLS models (binary outcome)
###########

## Supreme Court
# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out2_strongsup <- glm(Tr ~ party2 + factor(strongsup) + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + factor(prov), 
                   family = binomial(link = "probit"), data = rizzo2_strongsup)
e <- fitted(ps.out2_strongsup, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match2_strongsup <- data.frame(model.matrix(ps.out2_strongsup))
names(match2_strongsup)
  # Remove intercept and prov
match2_strongsup <- match2_strongsup[,-c(1, 20:31)]
names(match2_strongsup)
  # Add linearized estimated propensity scores
match2_strongsup$l <- l
names(match2_strongsup)
  # Add in other variables
match2_strongsup <- cbind("trustbi" = rizzo2_strongsup$trustbi, 
                    "Tr" = rizzo2_strongsup$Tr, 
                    "city" = rizzo2_strongsup$city, # City (clustered SEs and city FE)
                    "date" = rizzo2_strongsup$date, # Date of interview (clustered SEs)
                    "prov" = rizzo2_strongsup$prov, # Province (province FE)
                    match2_strongsup, 
                    "trustord" = rizzo2_strongsup$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo2_strongsup$trust)  # scaled outcome (appendix analysis))
names(match2_strongsup)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 35 minutes
  # Solution Found Generation 23
  # Number of Generations Run 74
set.seed(1)
gm.out2_strongsup <-	GenMatch(Tr = match2_strongsup$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match2_strongsup[, c(6:24)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out2_strongsup, file = "genetic-matching-output/gen-match-output-strongsup.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-strongsup.RData")

# Use Match() to obtain dataset of matched observations
mout2_strongsup <- Match(Y = match2_strongsup$trustbi,
                   Tr = match2_strongsup$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match2_strongsup[, c(6:24)], 
                   Weight.matrix = gm.out2_strongsup,
                   BiasAdjust = T,
                   ties=T,
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_strongsup$index.treated, mout2_strongsup$index.control)
# Create dataset of matches
GM_strongsup <- match2_strongsup[sel,]
# Add weights
GM_strongsup$w <- c(mout2_strongsup$weights, mout2_strongsup$weights)

names(GM_strongsup)
# Formula for regressions with strong-supporters covariate dataset
f_GM_strongsup <- as.formula(paste0("trustbi ~ Tr*party2*(factor.strongsup.1 + factor.strongsup.2) + ", 
                              paste0(paste0(names(GM_strongsup)[9:23], collapse = " + "), 
                                     " + factor(prov)")))

##  GM + WLS with bias adjustment
m_GM_strongsup <- lm(f_GM_strongsup, data = GM_strongsup, weights = w)

### Save models for tables and figure
GM_strongsup_model <- list("GM_strong_supporters" = m_GM_strongsup, 
                     "GM_strongsup" = GM_strongsup)
save(GM_strongsup_model, file = "models/GM-strong-supporters.RData")

### Prep data for figure D1.1

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call OLS models
load("models/OLS-strong-supporters.RData")
# Call entropy balancing binary models
load("models/EB-strong-supporters.RData")
# Call genetic matching models
load("models/GM-strong-supporters.RData")

names(OLS_strongsup_model)
names(EB_strongsup_model)
names(GM_strongsup_model)

m1 <- OLS_strongsup_model[["OLS_strong_supporters"]] # OLS model
rizzo2_strongsup <- OLS_strongsup_model[["rizzo2_strongsup"]] # OLS dataset

m2 <- EB_strongsup_model[["EB_strong_supporters"]] # EB model
EB_strongsup <- EB_strongsup_model[["EB_strongsup"]] # EB dataset

m3 <- GM_strongsup_model[["GM_strong_supporters"]] # GM model
GM_strongsup <- GM_strongsup_model[["GM_strongsup"]] # GM dataset

## Compute variance-covariance matrices
vcov1 <- vcovCL(m1, cluster = ~city + date, type = "HC1")
vcov2 <- vcovCL(m2, cluster = ~city + date, type = "HC1")
vcov3 <- vcovCL(m3, cluster = ~city + date, type = "HC1")


## Calculate first differences
# OLS
strongsup_OLS <- cbind(as.data.frame(summary(margins(m1, variable = "Tr", at = list(strongsup = 0:2, 
                                                                                       party2 = 0:1), vcov = vcov1))
), 
as.data.frame(summary(margins(m1, variable = "Tr", at = list(strongsup = 0:2, 
                                                                party2 = 0:1), vcov = vcov1), 
                      level = 0.9)
)[8:9])

names(strongsup_OLS)[10:11] <- c("lower90", "upper90")
strongsup_OLS$model <- "OLS"

head(strongsup_OLS)

strongsup_EB <- rbind(
  # not very strong supporters
  cbind(as.data.frame(summary(margins(m2, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                        factor.strongsup.2 = 0, 
                                                                        party2 = 0:1), vcov = vcov2))), 
        as.data.frame(summary(margins(m2, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                        factor.strongsup.2 = 0, 
                                                                        party2 = 0:1), vcov = vcov2), 
                              level = 0.9)
        )[9:10]
        
  ), 
  # quite strong supporters
  cbind(as.data.frame(summary(margins(m2, variable = "Tr", at = list(factor.strongsup.1 = 1, 
                                                                        factor.strongsup.2 = 0, 
                                                                        party2 = 0:1), vcov = vcov2))
  ),
  as.data.frame(summary(margins(m2, variable = "Tr", at = list(factor.strongsup.1 = 1, 
                                                                  factor.strongsup.2 = 0, 
                                                                  party2 = 0:1), vcov = vcov2), 
                        level = 0.9)
  )[9:10]
  
  ),
  # very strong supporters
  cbind(as.data.frame(summary(margins(m2, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                        factor.strongsup.2 = 1, 
                                                                        party2 = 0:1), vcov = vcov2))
  ), 
  as.data.frame(summary(margins(m2, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                  factor.strongsup.2 = 1, 
                                                                  party2 = 0:1), vcov = vcov2), 
                        level = 0.9)
  )[9:10]
  )
)
strongsup_EB
names(strongsup_EB)[11:12] <- c("lower90", "upper90")
strongsup_EB$model <- "EB"
head(strongsup_EB)

strongsup_GM <- rbind(
  # not very strong supporters
  cbind(as.data.frame(summary(margins(m3, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                        factor.strongsup.2 = 0, 
                                                                        party2 = 0:1), vcov = vcov3))
  ), 
  as.data.frame(summary(margins(m3, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                  factor.strongsup.2 = 0, 
                                                                  party2 = 0:1), vcov = vcov3), 
                        level = 0.9)
  )[9:10]
  ), 
  # quite strong supporters
  cbind(as.data.frame(summary(margins(m3, variable = "Tr", at = list(factor.strongsup.1 = 1, 
                                                                        factor.strongsup.2 = 0, 
                                                                        party2 = 0:1), vcov = vcov3))
  ), 
  as.data.frame(summary(margins(m3, variable = "Tr", at = list(factor.strongsup.1 = 1, 
                                                                  factor.strongsup.2 = 0, 
                                                                  party2 = 0:1), vcov = vcov3), 
                        level = 0.9)
  )[9:10]
  ), 
  # very strong supporters
  cbind(as.data.frame(summary(margins(m3, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                        factor.strongsup.2 = 1, 
                                                                        party2 = 0:1), vcov = vcov3))
  ), 
  as.data.frame(summary(margins(m3, variable = "Tr", at = list(factor.strongsup.1 = 0, 
                                                                  factor.strongsup.2 = 1, 
                                                                  party2 = 0:1), vcov = vcov3), 
                        level = 0.9)
  )[9:10]
  )
)
strongsup_GM
names(strongsup_GM)[11:12] <- c("lower90", "upper90")
strongsup_GM$model <- "GM"
head(strongsup_GM)

## stack EB and GM
strongsup_EB_GM <- rbind(strongsup_EB, strongsup_GM)

# merge 'factor.strongsup.1' and 'factor.strongsup.2' columns so to match those of 'strongsup_OLS
head(strongsup_OLS)
head(strongsup_EB_GM)
# create strongsup indicator
strongsup_EB_GM$strongsup <- ifelse(strongsup_EB_GM$factor.strongsup.1 == 0 
                                    & strongsup_EB_GM$factor.strongsup.2 ==0 , 0, 
                                    ifelse(strongsup_EB_GM$factor.strongsup.1 == 1 
                                           & strongsup_EB_GM$factor.strongsup.2 ==0 , 1,
                                           ifelse(strongsup_EB_GM$factor.strongsup.1 == 0 
                                                  & strongsup_EB_GM$factor.strongsup.2 ==1, 2,
                                                  NA)))
head(strongsup_EB_GM)
# Drop redundant columns ('factor.strongsup.1' and 'factor.strongsup.2')
strongsup_EB_GM <- strongsup_EB_GM[-c(2:3)]
names(strongsup_EB_GM)
# move 'strongsup' to second column
strongsup_EB_GM <- strongsup_EB_GM[,c(1,12,2:11)]

# stack all models
strongsup <- rbind(strongsup_OLS, strongsup_EB_GM)

strongsup

### Create figure D1.1

## vectors of point estimates and CIs by model
#### OLS
# point estimates
OLSpe <- c(strongsup$AME[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
           strongsup$AME[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
           strongsup$AME[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
           strongsup$AME[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
           strongsup$AME[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
           strongsup$AME[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
          )
# 95 CIs
OLS95u <- c(strongsup$upper[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$upper[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$upper[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$upper[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$upper[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$upper[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
OLS95l <- c(strongsup$lower[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$lower[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$lower[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$lower[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$lower[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$lower[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
# 90 CIs
OLS90u <- c(strongsup$upper90[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$upper90[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$upper90[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$upper90[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$upper90[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$upper90[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
OLS90l <- c(strongsup$lower90[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$lower90[strongsup$model=="OLS" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$lower90[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$lower90[strongsup$model=="OLS" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$lower90[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$lower90[strongsup$model=="OLS" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
#### EB
# point estimates
EBpe <- c(strongsup$AME[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
           strongsup$AME[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
           strongsup$AME[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
           strongsup$AME[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
           strongsup$AME[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
           strongsup$AME[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
          )
# 95 CIs
EB95u <- c(strongsup$upper[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$upper[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$upper[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$upper[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$upper[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$upper[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
EB95l <- c(strongsup$lower[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$lower[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$lower[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$lower[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$lower[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$lower[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
# 90 CIs
EB90u <- c(strongsup$upper90[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$upper90[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$upper90[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$upper90[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$upper90[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$upper90[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
EB90l <- c(strongsup$lower90[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$lower90[strongsup$model=="EB" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$lower90[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$lower90[strongsup$model=="EB" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$lower90[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$lower90[strongsup$model=="EB" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
#### GM
# point estimates
GMpe <- c(strongsup$AME[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
           strongsup$AME[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
           strongsup$AME[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
           strongsup$AME[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
           strongsup$AME[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
           strongsup$AME[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
          )
# 95 CIs
GM95u <- c(strongsup$upper[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$upper[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$upper[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$upper[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$upper[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$upper[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
GM95l <- c(strongsup$lower[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$lower[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$lower[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$lower[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$lower[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$lower[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
# 90 CIs
GM90u <- c(strongsup$upper90[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$upper90[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$upper90[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$upper90[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$upper90[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$upper90[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )
GM90l <- c(strongsup$lower90[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==0], # weak opposition supp
            strongsup$lower90[strongsup$model=="GM" & strongsup$strongsup == 0 & strongsup$party2==1],  # weak government supp
            strongsup$lower90[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==0], # moderate opposition supp
            strongsup$lower90[strongsup$model=="GM" & strongsup$strongsup == 1 & strongsup$party2==1],  # moderate government supp
            strongsup$lower90[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==0], # strong opposition supp
            strongsup$lower90[strongsup$model=="GM" & strongsup$strongsup == 2 & strongsup$party2==1]  # strong government supp
           )

## Set common features across panels
ylim <- c(min(strongsup$lower), max(strongsup$upper)) # range y axis
xlim <- c(0.90, 3.1)
xticks <- c(1, 2, 3) # ticks position
xlabels <- c("Not Very\nStrong", "Quite\nStrong", "Very\nStrong") # ticks labels
xseg <- c(0.95,1.05,1.95,2.05, 2.95, 3.05) # x_i segments
pts <- xseg # point estimates position
leglabel <- c("Opposition Supporters", "Government Supporters") # legend labels

# These options are common for all plots, 
# so set them up just once (as function or expression)
plots <- function(main, ylim, xlim) {
  plot(1, 1, xaxt = "n", yaxt = "n", 
       type = "n", ylab = "", xlab = "",
       main = main, 
       ylim = ylim, 
       xlim = xlim)
}

xaxis <- expression(
  axis(side = 1, at=xticks, las=1, labels = xlabels, 
       cex.axis=1.15, padj = 0.40)
)

yaxis <- expression(
  axis(side = 2, at = seq(-0.6,1,0.3), las = 1, labels = FALSE, 
       cex.axis = 1.15),
  text(x = 0.575, y = seq(-0.6,1,0.3), cex = 1.15, 
       labels = seq(-0.6,1,0.3), 
       srt = 90, 
       adj = 0.5, xpd = NA)
)

segs95 <- function(x0, y0, x1, y1) {
  segments(x0=x0, y0=y0, x1=x1, y1=y1, 
           lty = 1, lwd = 1.5, col = c("darkgray","black"))
}

segs90 <- function(x0, y0, x1, y1) {
  segments(x0=x0, y0=y0, x1=x1, y1=y1, 
           lty = 1, lwd = 3, col = c("darkgray","black"))
}

mypoints <- function(x, y) {
  points(x = x, y = y, 
         pch = c(21,24), cex = 1.5,
         col = c("darkgray","black"), 
         bg = c("darkgray", "black"))
}

hline0 <- expression(abline(h = 0, col = "red", lty=2))

## Set up layout for panel
#png(file = "fig/png-figures/strong-supporters-moderator.png", width = 7, height = 2.65, units = "in", res = 600)
#tiff(file = "fig/tiff-figures/strong-supporters-moderator.tif", width = 7, height = 2.65, units = "in", res = 600)
pdf(file = "fig/strong-supporters-moderator.pdf",   
    width = 7, # The width of the plot in inches
    height = 2.65) # The height of the plot in inches
par(mar=c(3.25, 3.5, 2, 1), oma=c(1, 0, 0, 0)) # Set up margins by number of lines
layout(matrix(1:3, ncol=3), # 3-panel figure
       widths=c(0.355, 0.3225,0.3225)) # relative widths (1st panel wider bc of ylab)

#### OLS
plots("OLS", ylim, xlim)
eval(xaxis)
eval(yaxis)
segs95(x0=xseg, y0=OLS95l,
       x1=xseg, y1=OLS95u)
segs90(x0=xseg, y0=OLS90l,
       x1=xseg, y1=OLS90u)
mypoints(x = pts, y = OLSpe)
eval(hline0)

title(ylab = "Effect of Supreme Court Decision", line = 2.2)

mtext(text = "Partisanship Strength", side = 1, 
      line = -0.25, outer = TRUE, cex = 0.8)

legend("topleft", cex = 1, pt.cex = 1.2, bty = "n",
       legend=leglabel, pch = c(21,24), 
       col = c("darkgray","black"), 
       pt.bg = c("darkgray","black"))

# Entropy Balacing
par(mar=c(3.25, 2, 2, 1))

plots(main = "Entropy Balancing + WLS", ylim = ylim, xlim = xlim)
eval(xaxis)
eval(yaxis)
segs95(x0=xseg, y0=EB95l, x1=xseg, y1=EB95u)
segs90(x0=xseg,y0=EB90l, x1=xseg, y1=EB90u)
mypoints(x = pts, y = EBpe)
eval(hline0)

# Matching models
plots(main = "Genetic Matching + WLS", ylim = ylim, xlim = xlim)
eval(xaxis)
eval(yaxis)
segs95(x0=xseg, y0= GM95l, x1=xseg, y1= GM95u)
segs90(x0=xseg, y0= GM90l, x1=xseg, y1= GM90u)
mypoints(x= pts, y = GMpe)
eval(hline0)

# save plot
dev.off()


#################################################
#### Alternative specifications
#### Appendix: tables F1.1 to F6.1 ####
#################################################

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

###########################################
# Appendix: Tables F1 (Binary, Ordinal, and Scaled Outcomes)

# Call EB and GM datasets
load("models/EB-limited-covariates.RData")
load("models/GM-limited-covariates.RData")

names(EB_lim)
names(GM_lim)

# Lower Court data (limited set of covariates)
EB_lim_low <- EB_lim[["EB_lim_low"]] # EB dataset
GM_lim_low <- GM_lim[["GM_lim_low"]] # GM dataset

# Supreme Court data (limited set of covariates)
EB_lim_sup <- EB_lim[["EB_lim_sup"]] # EB dataset
GM_lim_sup <- GM_lim[["GM_lim_sup"]] # GM dataset


#############
### Binary (Logit)
# Table F1.1
############

# Fomulae for binary logit models
f_OLS_logit <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(prov)")
f_EB_logit <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(EB_lim_low)[7:21], collapse = " + "), 
                                     " + factor(prov)")))
f_GM_logit <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_lim_low)[7:21], collapse = " + "), 
                                     " + factor(prov)")))

## Fit models
m1_logit <- glm(f_OLS_logit, data = rizzo1_lim, family = binomial(link = "logit"))
m2_logit <- glm(f_EB_logit, weights = w, data = EB_lim_low, family = binomial(link = "logit"))
m3_logit <- glm(f_GM_logit, weights = w, data = GM_lim_low, family = binomial(link = "logit"))
m4_logit <- glm(f_OLS_logit, data = rizzo2_lim, family = binomial(link = "logit"))
m5_logit <- glm(f_EB_logit, weights = w, data = EB_lim_sup, family = binomial(link = "logit"))
m6_logit <- glm(f_GM_logit, weights = w, data = GM_lim_sup, family = binomial(link = "logit"))

## Compute cluster-robust standard errors
se1_logit <- coeftest(m1_logit, vcovCL(m1_logit, cluster = ~ city + date, type = "HC1"))[,2]
se2_logit <- coeftest(m2_logit, vcovCL(m2_logit, cluster = ~ city + date, type = "HC1"))[,2]
se3_logit <- coeftest(m3_logit, vcovCL(m3_logit, cluster = ~ city + date, type = "HC1"))[,2]
se4_logit <- coeftest(m4_logit, vcovCL(m4_logit, cluster = ~ city + date, type = "HC1"))[,2]
se5_logit <- coeftest(m5_logit, vcovCL(m5_logit, cluster = ~ city + date, type = "HC1"))[,2]
se6_logit <- coeftest(m6_logit, vcovCL(m6_logit, cluster = ~ city + date, type = "HC1"))[,2]

## Create table
logit_tab <- stargazer(m1_logit, m2_logit, m3_logit, m4_logit, m5_logit, m6_logit,
                          se=list(se1_logit, se2_logit, se3_logit, se4_logit, se5_logit, se6_logit),
                          title="Binary Outcome (Logit)", align=TRUE,
                          dep.var.labels.include = FALSE, 
                          dep.var.caption = "",
                          label = "tab:logit",
                          column.labels = c("\\textbf{Lower Court}",
                                            "\\textbf{Supreme Court}"),
                          column.separate = c(3, 3),
                          keep = c("Tr", "party2", "Constant"),
                          covariate.labels = c("Court Ruling","Government Supporter", 
                                               "C. Ruling $\\times$ Gov. Supporter"),
                          star.char = c("+", "*", "**", "***"),
                          star.cutoffs = c(.1, .05, .01, .001),
                          notes.append=FALSE, notes.align = "l", notes.label = "",
                          omit.stat=c("f", "ser", "rsq"),
                          header = FALSE,
                          no.space = TRUE,
                          notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                          table.placement = "H",
                          add.lines = list(c("\\midrule Controls?",
                                             "\\multicolumn{1}{c}{\\checkmark}", 
                                             "\\multicolumn{1}{c}{\\checkmark}",
                                             "\\multicolumn{1}{c}{\\checkmark}",
                                             "\\multicolumn{1}{c}{\\checkmark}",
                                             "\\multicolumn{1}{c}{\\checkmark}", 
                                             "\\multicolumn{1}{c}{\\checkmark}"),
                                           c("Province FE?",
                                             "\\multicolumn{1}{c}{\\checkmark}", 
                                             "\\multicolumn{1}{c}{\\checkmark}",
                                             "\\multicolumn{1}{c}{\\checkmark}",
                                             "\\multicolumn{1}{c}{\\checkmark}",
                                             "\\multicolumn{1}{c}{\\checkmark}", 
                                             "\\multicolumn{1}{c}{\\checkmark}"))
                        )
# Format table for publication
logit_tab
logit_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", logit_tab, fixed=TRUE)
logit_tab <- gsub("\\hline \\\\[-1.8ex] ", "", logit_tab, fixed=TRUE)
logit_tab <- gsub("\\hline ", "\\bottomrule", logit_tab, fixed=TRUE)
logit_tab <- gsub("[-1.8ex] ", "", logit_tab, fixed=TRUE)
logit_tab <- gsub("  \\label{tab:probit} ", 
                     "\\tabcolsep=8pt  \\label{tab:probit}  \\resizebox{\\linewidth}{!}{%", logit_tab, fixed=TRUE)
logit_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", logit_tab, fixed=TRUE)
logit_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                     "\\begin{tabular}{l*{6}{d{1.3}}}", logit_tab, fixed=TRUE)
logit_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                     " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", logit_tab, fixed=TRUE)
logit_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                     "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", logit_tab, fixed=TRUE)
logit_tab <- gsub("Akaike Inf. Crit. ", "AIC ", logit_tab, fixed=TRUE)

sink("tab/logit.tex")
cat(logit_tab, sep="\n")
sink()



#############
### Ordinal (Ordered Probit)
# Table F1.2
############

# Fomulae for ordered probit models
f_OLS_ord <- as.formula("trustord ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(prov)")
f_EB_ord <- as.formula(paste0("trustord ~ Tr*party2 + ", 
                              paste0(paste0(names(EB_lim_low)[7:21], collapse = " + "), 
                                     " + factor(prov)")))
f_GM_ord <- as.formula(paste0("trustord ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_lim_low)[7:21], collapse = " + "), 
                                     " + factor(prov)")))

## Fit models
m1_ord <- polr(f_OLS_ord, data = rizzo1_lim, method = "probit", Hess = TRUE)
m2_ord <- polr(f_EB_ord, weights = w, data = EB_lim_low, method = "probit", Hess = TRUE)
m3_ord <- polr(f_GM_ord, weights = w, data = GM_lim_low, method = "probit", Hess = TRUE)
m4_ord <- polr(f_OLS_ord, data = rizzo2_lim, method = "probit", Hess = TRUE)
m5_ord <- polr(f_EB_ord, weights = w, data = EB_lim_sup, method = "probit", Hess = TRUE)
m6_ord <- polr(f_GM_ord, weights = w, data = GM_lim_sup, method = "probit", Hess = TRUE)
## Compute cluster-robust standard errors
se1_ord <- coeftest(m1_ord, vcovCL(m1_ord, cluster = ~ city + date, type = "HC1"))[,2]
se2_ord <- coeftest(m2_ord, vcovCL(m2_ord, cluster = ~ city + date, type = "HC1"))[,2]
se3_ord <- coeftest(m3_ord, vcovCL(m3_ord, cluster = ~ city + date, type = "HC1"))[,2]
se4_ord <- coeftest(m4_ord, vcovCL(m4_ord, cluster = ~ city + date, type = "HC1"))[,2]
se5_ord <- coeftest(m5_ord, vcovCL(m5_ord, cluster = ~ city + date, type = "HC1"))[,2]
se6_ord <- coeftest(m6_ord, vcovCL(m6_ord, cluster = ~ city + date, type = "HC1"))[,2]

# Cut offs
theta1 <- round(c(m1_ord$zeta[1], m2_ord$zeta[1], m3_ord$zeta[1], 
                  m4_ord$zeta[1], m5_ord$zeta[1], m6_ord$zeta[1]),3)
theta_se1 <- paste0("(",round(c(sqrt(diag(vcovCL(m1_ord, cluster = ~ city + date, type = "HC1")))["None|A Little"], 
                     sqrt(diag(vcovCL(m2_ord, cluster = ~ city + date, type = "HC1")))["None|A Little"], 
                     sqrt(diag(vcovCL(m3_ord, cluster = ~ city + date, type = "HC1")))["None|A Little"], 
                     sqrt(diag(vcovCL(m4_ord, cluster = ~ city + date, type = "HC1")))["None|A Little"], 
                     sqrt(diag(vcovCL(m5_ord, cluster = ~ city + date, type = "HC1")))["None|A Little"], 
                     sqrt(diag(vcovCL(m6_ord, cluster = ~ city + date, type = "HC1")))["None|A Little"]), 3),")")
theta2 <- round(c(m1_ord$zeta[2], m2_ord$zeta[2], m3_ord$zeta[2], 
                  m4_ord$zeta[2],m5_ord$zeta[2], m6_ord$zeta[2]),3)
theta_se2 <- paste0("(",round(c(sqrt(diag(vcovCL(m1_ord, cluster = ~ city + date, type = "HC1")))["A Little|Some"], 
                     sqrt(diag(vcovCL(m2_ord, cluster = ~ city + date, type = "HC1")))["A Little|Some"], 
                     sqrt(diag(vcovCL(m3_ord, cluster = ~ city + date, type = "HC1")))["A Little|Some"], 
                     sqrt(diag(vcovCL(m4_ord, cluster = ~ city + date, type = "HC1")))["A Little|Some"], 
                     sqrt(diag(vcovCL(m5_ord, cluster = ~ city + date, type = "HC1")))["A Little|Some"], 
                     sqrt(diag(vcovCL(m6_ord, cluster = ~ city + date, type = "HC1")))["A Little|Some"]), 3),")")
theta3 <- round(c(m1_ord$zeta[3], m2_ord$zeta[3], m3_ord$zeta[3], 
                  m4_ord$zeta[3], m5_ord$zeta[3], m6_ord$zeta[3]),3)
theta_se3 <- paste0("(", round(c(sqrt(diag(vcovCL(m1_ord, cluster = ~ city + date, type = "HC1")))["Some|A Lot"], 
                     sqrt(diag(vcovCL(m2_ord, cluster = ~ city + date, type = "HC1")))["Some|A Lot"], 
                     sqrt(diag(vcovCL(m3_ord, cluster = ~ city + date, type = "HC1")))["Some|A Lot"], 
                     sqrt(diag(vcovCL(m4_ord, cluster = ~ city + date, type = "HC1")))["Some|A Lot"], 
                     sqrt(diag(vcovCL(m5_ord, cluster = ~ city + date, type = "HC1")))["Some|A Lot"], 
                     sqrt(diag(vcovCL(m6_ord, cluster = ~ city + date, type = "HC1")))["Some|A Lot"]), 3),")")

# Create table
ordered_probit_tab <- stargazer(m1_ord, m2_ord, m3_ord, m4_ord, m5_ord, m6_ord,
                        se=list(se1_ord, se2_ord, se3_ord, se4_ord, se5_ord, se6_ord),
                        title="Ordinal Outcome (Ordered Probit)", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:ordered-probit",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("Tr", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary (``None\"; ``A little\"; ``Some\"; ``A lot\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule None $\\vert$ A Little", theta1), 
                                         c("", theta_se1), 
                                         c("A Little $\\vert$ Some", theta2), 
                                         c("", theta_se2), 
                                         c("Some $\\vert$ A Lot", theta3), 
                                         c("", theta_se3), 
                                         c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("Province FE?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"))
)
# Format table for publication
ordered_probit_tab
ordered_probit_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub("\\hline \\\\[-1.8ex] ", "", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub("\\hline ", "\\bottomrule", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub("[-1.8ex] ", "", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub("  \\label{tab:ordered-probit} ", 
                   "\\tabcolsep=8pt  \\label{tab:ordered-probit}  \\resizebox{\\linewidth}{!}{%", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                   "\\begin{tabular}{l*{6}{d{1.3}}}", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                   " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", ordered_probit_tab, fixed=TRUE)
ordered_probit_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                   "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", ordered_probit_tab, fixed=TRUE)

sink("tab/ordered-probit.tex")
cat(ordered_probit_tab, sep="\n")
sink()


#############
### Scaled (OLS)
# Table F1.3
############

# Fomulae for scaled outcome models
f_OLS_sc <- as.formula("trust ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(prov)")
f_EB_sc <- as.formula(paste0("trust ~ Tr*party2 + ", 
                              paste0(paste0(names(EB_lim_low)[7:21], collapse = " + "), 
                                     " + factor(prov)")))
f_GM_sc <- as.formula(paste0("trust ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_lim_low)[7:21], collapse = " + "), 
                                     " + factor(prov)")))

## Fit models
m1_sc <- lm(f_OLS_sc, data = rizzo1_lim)
m2_sc <- lm(f_EB_sc, weights = w, data = EB_lim_low)
m3_sc <- lm(f_GM_sc, weights = w, data = GM_lim_low)
m4_sc <- lm(f_OLS_sc, data = rizzo2_lim)
m5_sc <- lm(f_EB_sc, weights = w, data = EB_lim_sup)
m6_sc <- lm(f_GM_sc, weights = w, data = GM_lim_sup)

## Compute cluster-robust standard errors
se1_sc <- coeftest(m1_sc, vcovCL(m1_sc, cluster = ~ city + date, type = "HC1"))[,2]
se2_sc <- coeftest(m2_sc, vcovCL(m2_sc, cluster = ~ city + date, type = "HC1"))[,2]
se3_sc <- coeftest(m3_sc, vcovCL(m3_sc, cluster = ~ city + date, type = "HC1"))[,2]
# vcovCL doesn't compute some SEs (NaN), so use feols() from the fixest package
se4_sc <- feols(f_OLS_sc, cluster = ~city+date, data = rizzo1_lim)[["se"]]
se5_sc <- coeftest(m5_sc, vcovCL(m5_sc, cluster = ~ city + date, type = "HC1"))[,2]
se6_sc <- coeftest(m6_sc, vcovCL(m6_sc, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1_sc$resid + m1_sc$fitted.values), 
                 mean(m2_sc$resid + m2_sc$fitted.values),
                 mean(m3_sc$resid + m3_sc$fitted.values),
                 mean(m4_sc$resid + m4_sc$fitted.values),
                 mean(m5_sc$resid + m5_sc$fitted.values),
                 mean(m6_sc$resid + m6_sc$fitted.values)),3)
Y_sd <- round(c(sd(m1_sc$resid + m1_sc$fitted.values), 
                sd(m2_sc$resid + m2_sc$fitted.values),
                sd(m3_sc$resid + m3_sc$fitted.values),
                sd(m4_sc$resid + m4_sc$fitted.values),
                sd(m5_sc$resid + m5_sc$fitted.values),
                sd(m6_sc$resid + m6_sc$fitted.values)),3)

# Create table
scaled_tab <- stargazer(m1_sc, m2_sc, m3_sc, m4_sc, m5_sc, m6_sc,
                        se=list(se1_sc, se2_sc, se3_sc, se4_sc, se5_sc, se6_sc),
                        title="Scaled Outcome (OLS)", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:scaled",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("Tr", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``None\"; $0.33=$ ``A little\"; $0.67=$ ``Some\"; $1=$ ``A lot\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                         c("sd(Trust)", Y_sd),
                                         c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("City FE?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"))
)
# Format table for publication
scaled_tab
scaled_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", scaled_tab, fixed=TRUE)
scaled_tab <- gsub("\\hline \\\\[-1.8ex] ", "", scaled_tab, fixed=TRUE)
scaled_tab <- gsub("\\hline ", "\\bottomrule", scaled_tab, fixed=TRUE)
scaled_tab <- gsub("[-1.8ex] ", "", scaled_tab, fixed=TRUE)
scaled_tab <- gsub("  \\label{tab:scaled} ", 
                   "\\tabcolsep=8pt  \\label{tab:scaled}  \\resizebox{\\linewidth}{!}{%", scaled_tab, fixed=TRUE)
scaled_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", scaled_tab, fixed=TRUE)
scaled_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                   "\\begin{tabular}{l*{6}{d{1.3}}}", scaled_tab, fixed=TRUE)
scaled_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                   " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", scaled_tab, fixed=TRUE)
scaled_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                   "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", scaled_tab, fixed=TRUE)

sink("tab/scaled.tex")
cat(scaled_tab, sep="\n")
sink()


###########################################
# Appendix: Tables F2 (Standard Errors)

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))


# Call models
load("models/OLS-limited-covariates.RData")
load("models/EB-limited-covariates.RData")
load("models/GM-limited-covariates.RData")

names(OLS_lim)
names(EB_lim)
names(GM_lim)

# Lower Court models (limited set of covariates)
m1 <- OLS_lim[["OLS_lim_lower"]] # OLS model
m2 <- EB_lim[["EB_lim_lower"]] # EB model
EB_lim_low <- EB_lim[["EB_lim_low"]] # EB dataset
m3 <- GM_lim[["GM_lim_lower"]] # GM model
GM_lim_low <- GM_lim[["GM_lim_low"]] # GM dataset

# Supreme Court models (limited set of covariates)
m4 <- OLS_lim[["OLS_lim_supreme"]] # OLS model
m5 <- EB_lim[["EB_lim_supreme"]] # EB model
EB_lim_sup <- EB_lim[["EB_lim_sup"]] # EB dataset
m6 <- GM_lim[["GM_lim_supreme"]] # GM model
GM_lim_sup <- GM_lim[["GM_lim_sup"]] # GM dataset

#############
### (Cluster) bootstrap standard errors (Webb 2014)
# Table F2.1
############

## Compute cluster-robust standard errors
set.seed(1)
se1_boot <- coeftest(m1, vcovBS(m1, cluster = ~ city + date, type = "webb", R = 100000))[,2]
se2_boot <- coeftest(m2, vcovBS(m2, cluster = ~ city + date, type = "webb", R = 100000))[,2]
se3_boot <- coeftest(m3, vcovBS(m3, cluster = ~ city + date, type = "webb", R = 100000))[,2]
se4_boot <- coeftest(m4, vcovBS(m4, cluster = ~ city + date, type = "webb", R = 100000))[,2]
se5_boot <- coeftest(m5, vcovBS(m5, cluster = ~ city + date, type = "webb", R = 100000))[,2]
se6_boot <- coeftest(m6, vcovBS(m6, cluster = ~ city + date, type = "webb", R = 100000))[,2]

boot_tab <- stargazer(m1, m2, m3, m4, m5, m6,
                        se=list(se1_boot, se2_boot, se3_boot, se4_boot, se5_boot, se6_boot),
                        title="(Cluster) Bootstrap Standard Errors by City and Date", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:boot",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("Tr", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview using the wild bootstrap procedure suggested by Webb (2014) with \\texttt{R = 100,000} bootstrap replications. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("Province FE?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"))
                      )
# Format table for publication
boot_tab
boot_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", boot_tab, fixed=TRUE)
boot_tab <- gsub("\\hline \\\\[-1.8ex] ", "", boot_tab, fixed=TRUE)
boot_tab <- gsub("\\hline ", "\\bottomrule", boot_tab, fixed=TRUE)
boot_tab <- gsub("[-1.8ex] ", "", boot_tab, fixed=TRUE)
boot_tab <- gsub("  \\label{tab:boot} ", 
                   "\\tabcolsep=8pt  \\label{tab:boot}  \\resizebox{\\linewidth}{!}{%", boot_tab, fixed=TRUE)
boot_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", boot_tab, fixed=TRUE)
boot_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                   "\\begin{tabular}{l*{6}{d{1.3}}}", boot_tab, fixed=TRUE)
boot_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                   " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", boot_tab, fixed=TRUE)
boot_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                   "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", boot_tab, fixed=TRUE)

sink("tab/cluster-bootstrap-se.tex")
cat(boot_tab, sep="\n")
sink()


#############
### Clustered by city only
# Table F2.2
############

se1_city <- coeftest(m1, vcovCL(m1, cluster = ~ city, type = "HC1"))[,2]
se2_city <- coeftest(m2, vcovCL(m2, cluster = ~ city, type = "HC1"))[,2]
se3_city <- coeftest(m3, vcovCL(m3, cluster = ~ city, type = "HC1"))[,2]
se4_city <- coeftest(m4, vcovCL(m4, cluster = ~ city, type = "HC1"))[,2]
se5_city <- coeftest(m5, vcovCL(m5, cluster = ~ city, type = "HC1"))[,2]
se6_city <- coeftest(m6, vcovCL(m6, cluster = ~ city, type = "HC1"))[,2]

city_tab <- stargazer(m1, m2, m3, m4, m5, m6,
                      se=list(se1_city, se2_city, se3_city, se4_city, se5_city, se6_city),
                      title="Standard Errors Clustered Only by City", align=TRUE,
                      dep.var.labels.include = FALSE, 
                      dep.var.caption = "",
                      label = "tab:city",
                      column.labels = c("\\textbf{Lower Court}",
                                        "\\textbf{Supreme Court}"),
                      column.separate = c(3, 3),
                      keep = c("Tr", "party2", "Constant"),
                      covariate.labels = c("Court Ruling","Government Supporter", 
                                           "C. Ruling $\\times$ Gov. Supporter"),
                      star.char = c("+", "*", "**", "***"),
                      star.cutoffs = c(.1, .05, .01, .001),
                      notes.append=FALSE, notes.align = "l", notes.label = "",
                      omit.stat=c("f", "ser", "rsq"),
                      header = FALSE,
                      no.space = TRUE,
                      notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                      table.placement = "H",
                      add.lines = list(c("\\midrule Controls?",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}"),
                                       c("Province FE?",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}"))
)
# Format table for publication
city_tab
city_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", city_tab, fixed=TRUE)
city_tab <- gsub("\\hline \\\\[-1.8ex] ", "", city_tab, fixed=TRUE)
city_tab <- gsub("\\hline ", "\\bottomrule", city_tab, fixed=TRUE)
city_tab <- gsub("[-1.8ex] ", "", city_tab, fixed=TRUE)
city_tab <- gsub("  \\label{tab:city} ", 
                 "\\tabcolsep=8pt  \\label{tab:city}  \\resizebox{\\linewidth}{!}{%", city_tab, fixed=TRUE)
city_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", city_tab, fixed=TRUE)
city_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                 "\\begin{tabular}{l*{6}{d{1.3}}}", city_tab, fixed=TRUE)
city_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                 " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", city_tab, fixed=TRUE)
city_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                 "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", city_tab, fixed=TRUE)

sink("tab/city-se.tex")
cat(city_tab, sep="\n")
sink()


#############
### Clustered by date only
# Table F2.3
############

se1_date <- coeftest(m1, vcovCL(m1, cluster = ~ date, type = "HC1"))[,2]
se2_date <- coeftest(m2, vcovCL(m2, cluster = ~ date, type = "HC1"))[,2]
se3_date <- coeftest(m3, vcovCL(m3, cluster = ~ date, type = "HC1"))[,2]
se4_date <- coeftest(m4, vcovCL(m4, cluster = ~ date, type = "HC1"))[,2]
se5_date <- coeftest(m5, vcovCL(m5, cluster = ~ date, type = "HC1"))[,2]
se6_date <- coeftest(m6, vcovCL(m6, cluster = ~ date, type = "HC1"))[,2]

date_tab <- stargazer(m1, m2, m3, m4, m5, m6,
                      se=list(se1_date, se2_date, se3_date, se4_date, se5_date, se6_date),
                      title="Standard Errors Clustered Only by Date of Survey Interview", align=TRUE,
                      dep.var.labels.include = FALSE, 
                      dep.var.caption = "",
                      label = "tab:date",
                      column.labels = c("\\textbf{Lower Court}",
                                        "\\textbf{Supreme Court}"),
                      column.separate = c(3, 3),
                      keep = c("Tr", "party2", "Constant"),
                      covariate.labels = c("Court Ruling","Government Supporter", 
                                           "C. Ruling $\\times$ Gov. Supporter"),
                      star.char = c("+", "*", "**", "***"),
                      star.cutoffs = c(.1, .05, .01, .001),
                      notes.append=FALSE, notes.align = "l", notes.label = "",
                      omit.stat=c("f", "ser", "rsq"),
                      header = FALSE,
                      no.space = TRUE,
                      notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                      table.placement = "H",
                      add.lines = list(c("\\midrule Controls?",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}"),
                                       c("Province FE?",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}",
                                         "\\multicolumn{1}{c}{\\checkmark}", 
                                         "\\multicolumn{1}{c}{\\checkmark}"))
)
# Format table for publication
date_tab
date_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", date_tab, fixed=TRUE)
date_tab <- gsub("\\hline \\\\[-1.8ex] ", "", date_tab, fixed=TRUE)
date_tab <- gsub("\\hline ", "\\bottomrule", date_tab, fixed=TRUE)
date_tab <- gsub("[-1.8ex] ", "", date_tab, fixed=TRUE)
date_tab <- gsub("  \\label{tab:date} ", 
                 "\\tabcolsep=8pt  \\label{tab:date}  \\resizebox{\\linewidth}{!}{%", date_tab, fixed=TRUE)
date_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", date_tab, fixed=TRUE)
date_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                 "\\begin{tabular}{l*{6}{d{1.3}}}", date_tab, fixed=TRUE)
date_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                 " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", date_tab, fixed=TRUE)
date_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                 "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", date_tab, fixed=TRUE)

sink("tab/date-se.tex")
cat(date_tab, sep="\n")
sink()


###########################################
# Appendix: Table F3 (City Fixed Effects)

# Fomulae for city FE models
f_OLS_cityFE <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(city)")
f_EB_cityFE <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(EB_lim_low)[7:21], collapse = " + "), 
                                     " + factor(city)")))
f_GM_cityFE <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_lim_low)[7:21], collapse = " + "), 
                                     " + factor(city)")))

m1_cityFE <- lm(f_OLS_cityFE, data = rizzo1_lim)
m2_cityFE <- lm(f_EB_cityFE, weights = w, data = EB_lim_low)
m3_cityFE <- lm(f_GM_cityFE, weights = w, data = GM_lim_low)
m4_cityFE <- lm(f_OLS_cityFE, data = rizzo2_lim)
m5_cityFE <- lm(f_EB_cityFE, weights = w, data = EB_lim_sup)
m6_cityFE <- lm(f_GM_cityFE, weights = w, data = GM_lim_sup)

## Compute cluster-robust standard errors
se1_cityFE <- coeftest(m1_cityFE, vcovCL(m1_cityFE, cluster = ~ city + date, type = "HC1"))[,2]
se2_cityFE <- coeftest(m2_cityFE, vcovCL(m2_cityFE, cluster = ~ city + date, type = "HC1"))[,2]
se3_cityFE <- coeftest(m3_cityFE, vcovCL(m3_cityFE, cluster = ~ city + date, type = "HC1"))[,2]
se4_cityFE <- coeftest(m4_cityFE, vcovCL(m4_cityFE, cluster = ~ city + date, type = "HC1"))[,2]
se5_cityFE <- coeftest(m5_cityFE, vcovCL(m5_cityFE, cluster = ~ city + date, type = "HC1"))[,2]
se6_cityFE <- coeftest(m6_cityFE, vcovCL(m6_cityFE, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1_cityFE$resid + m1_cityFE$fitted.values), 
                 mean(m2_cityFE$resid + m2_cityFE$fitted.values),
                 mean(m3_cityFE$resid + m3_cityFE$fitted.values),
                 mean(m4_cityFE$resid + m4_cityFE$fitted.values),
                 mean(m5_cityFE$resid + m5_cityFE$fitted.values),
                 mean(m6_cityFE$resid + m6_cityFE$fitted.values)),3)
Y_sd <- round(c(sd(m1_cityFE$resid + m1_cityFE$fitted.values), 
                sd(m2_cityFE$resid + m2_cityFE$fitted.values),
                sd(m3_cityFE$resid + m3_cityFE$fitted.values),
                sd(m4_cityFE$resid + m4_cityFE$fitted.values),
                sd(m5_cityFE$resid + m5_cityFE$fitted.values),
                sd(m6_cityFE$resid + m6_cityFE$fitted.values)),3)

cityFE_tab <- stargazer(m1_cityFE, m2_cityFE, m3_cityFE, m4_cityFE, m5_cityFE, m6_cityFE,
                        se=list(se1_cityFE, se2_cityFE, se3_cityFE, se4_cityFE, se5_cityFE, se6_cityFE),
                        title="City Fixed Effects", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:cityFE",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("W", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                         c("sd(Trust)", Y_sd),
                                         c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("City FE?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"))
                        )
# Format table for publication
cityFE_tab
cityFE_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub("\\hline \\\\[-1.8ex] ", "", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub("\\hline ", "\\bottomrule", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub("[-1.8ex] ", "", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub("  \\label{tab:cityFE} ", 
                   "\\tabcolsep=8pt  \\label{tab:cityFE}  \\resizebox{\\linewidth}{!}{%", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                   "\\begin{tabular}{l*{6}{d{1.3}}}", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                   " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", cityFE_tab, fixed=TRUE)
cityFE_tab <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                   "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", cityFE_tab, fixed=TRUE)

sink("tab/city-fixed-effects.tex")
cat(cityFE_tab, sep="\n")
sink()



###########################################
# Appendix: Table F4 (Removing 6/11 and 6/19 respondents)

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Limited set of covariates
sel_lim <-	!is.na(rizzo$Tr) &
  !is.na(rizzo$party2) &
  !is.na(rizzo$age) &
  !is.na(rizzo$trustbi) &
  !is.na(rizzo$female) &
  !is.na(rizzo$education) &
  !is.na(rizzo$SES_ord) &
  !is.na(rizzo$subinc_ord) &
  !is.na(rizzo$class_ord) &
  !is.na(rizzo$religion) &
  !is.na(rizzo$city)

table(sel_lim)
rizzo11_18 <- rizzo[sel_lim,]
dim(rizzo11_18)

# Drop 6/11 and 6/18 respondents
rizzo11_18 <- rizzo11_18[rizzo11_18$date != 11 & rizzo11_18$date != 18, ]

table(rizzo11_18$date, rizzo11_18$Tr)
rizzo1_11_18 <- rizzo11_18[rizzo11_18$Tr != 2, ]
rizzo2_11_18 <- rizzo11_18[rizzo11_18$Tr != 1, ]
rizzo2_11_18$Tr <- ifelse(rizzo2_11_18$Tr == 2, 1, 0)

### OLS models 
f_OLS <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(prov)")

## Lower court
m_OLS_low_11_18 <- lm(f_OLS, data = rizzo1_11_18)

## Supreme court
m_OLS_sup_11_18 <- lm(f_OLS, data = rizzo2_11_18)

### Save models for tables and figure
OLS_11_18 <- list("OLS_lower_11_18" = m_OLS_low_11_18, "OLS_supreme_11_18" = m_OLS_sup_11_18, 
                   "rizzo1_11_18" = rizzo1_11_18, "rizzo2_11_18" = rizzo2_11_18)
save(OLS_11_18, file = "models/OLS-limited-covariates-11-18-respondents.RData")

###########
### Entropy balance + WLS models (binary outcome)
###########

## Lower Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_low_11_18 <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo1_11_18))
)

colnames(EB_low_11_18)

  # Remove intercept
EB_low_11_18 <- EB_low_11_18[, -1]

colnames(EB_low_11_18)

  # Add in outcomes and missing variables
EB_low_11_18 <- cbind("trustbi" = rizzo1_11_18$trustbi, 
                 "city" = rizzo1_11_18$city, # City (clustered SEs and city FE)
                 "date" = rizzo1_11_18$date, # Date of interview (clustered SEs)
                 "prov" = rizzo1_11_18$prov, # Province (province FE)
                 EB_low_11_18, # Covariate matrix
                 "trustord" = rizzo1_11_18$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo1_11_18$trust)  # scaled outcome (appendix analysis)
names(EB_low_11_18)

  # Order observations to add entropy balance weights (controls first)
EB_low_11_18 <- rbind(EB_low_11_18[EB_low_11_18$Tr == 0,], 
                      EB_low_11_18[EB_low_11_18$Tr == 1,])

colnames(EB_low_11_18)

# Compute entropy balance (EB) weights
out1_lim <- ebalance(Treatment = EB_low_11_18$Tr, 
                     X = EB_low_11_18[,6:21]) # include only covariates to balance on

# Add weights to (ordered) dataset
EB_low_11_18$w <- c(out1_lim$w, # weights for control observations 
                  rep(1, nrow(EB_low_11_18[EB_low_11_18$Tr == 1,])))

# Check distribution of weights
hist(out1_lim$w, 100) # weights are well behaved

names(EB_low_11_18)

# Formula for regressions with limited covariate dataset
names(EB_low_11_18)
f_EB_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                       paste0(paste0(names(EB_low_11_18)[7:21], collapse = " + "), 
                              " + factor(prov)")))

# WLS with bias adjustment
m_EB_low_11_18 <- lm(f_EB_lim, data = EB_low_11_18, weights = w)


## Supreme Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_sup_11_18 <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_11_18))
)

colnames(EB_sup_11_18)

  # Remove intercept
EB_sup_11_18 <- EB_sup_11_18[, -1]

colnames(EB_sup_11_18)

  # Add in outcomes and missing variables
EB_sup_11_18 <- cbind("trustbi" = rizzo2_11_18$trustbi, 
                 "city" = rizzo2_11_18$city, # City (clustered SEs and city FE)
                 "date" = rizzo2_11_18$date, # Date of interview (clustered SEs)
                 "prov" = rizzo2_11_18$prov, # Province (province FE)
                 EB_sup_11_18, # Covariate matrix
                 "trustord" = rizzo2_11_18$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo2_11_18$trust)  # scaled outcome (appendix analysis)
names(EB_sup_11_18)

  # Order observations to add entropy balance weights (controls first)
EB_sup_11_18 <- rbind(EB_sup_11_18[EB_sup_11_18$Tr == 0,], 
                      EB_sup_11_18[EB_sup_11_18$Tr == 1,])

colnames(EB_sup_11_18)

# Compute entropy balance (EB) weights
out2_lim <- ebalance(Treatment = EB_sup_11_18$Tr, 
                     X = EB_sup_11_18[,6:21]) # include only covariates to balance on

# Check distribution of weights
hist(out2_lim$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_sup_11_18$w <- c(out2_lim$w, # weights for control observations 
                  rep(1, nrow(EB_sup_11_18[EB_sup_11_18$Tr == 1,])))

# WLS with bias adjustment
m_EB_sup_11_18 <- lm(f_EB_lim, data = EB_sup_11_18, weights = w)


### Save models for tables and figure
EB_11_18 <- list("EB_lower_11_18" = m_EB_low_11_18, "EB_supreme_11_18" = m_EB_sup_11_18, 
                "EB_low_11_18" = EB_low_11_18, "EB_sup_11_18" = EB_sup_11_18)
save(EB_11_18, file = "models/EB-limited-covariates-11-18-respondents.RData")


###########
### Genetic matching + WLS models (binary outcome)
###########

## Lower Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out1_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + factor(prov)
                   , 
                   family = binomial(link = "probit"), data = rizzo1_11_18)
e <- fitted(ps.out1_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match1_lim <- data.frame(model.matrix(ps.out1_lim))
names(match1_lim)
  # Remove intercept and prov
match1_lim <- match1_lim[,-c(1, 18:28)]
names(match1_lim)
  # Add linearized estimated propensity scores
match1_lim$l <- l
names(match1_lim)
  # Add in other variables
match1_lim <- cbind("trustbi" = rizzo1_11_18$trustbi, 
                    "Tr" = rizzo1_11_18$Tr, 
                    "city" = rizzo1_11_18$city, # City (clustered SEs and city FE)
                    "date" = rizzo1_11_18$date, # Date of interview (clustered SEs)
                    "prov" = rizzo1_11_18$prov, # Province (province FE)
                    match1_lim, 
                    "trustord" = rizzo1_11_18$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo1_11_18$trust)  # scaled outcome (appendix analysis))
names(match1_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores) 

# Computation takes about 30 minutes
  # Solution Found Generation 17
  # Number of Generations Run 68
set.seed(1)
gm.out1_lim <-	GenMatch(Tr = match1_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match1_lim[, c(6:22)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out1_lim, file = "genetic-matching-output/gen-match-output-lower-lim-11-18-respondents.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-lower-lim-11-18-respondents.RData")

names(match1_lim)

# Use Match() to obtain dataset of matched observations
mout1_lim <- Match(Y = match1_lim$trustbi, 
                  Tr = match1_lim$Tr, 
                  # Include only covariates (and linearized estimated propensity scores)
                  X = match1_lim[, c(6:22)], 
                  Weight.matrix = gm.out1_lim,
                  BiasAdjust = T,
                  ties=T, 
                  replace=T)

# Vectors of matched control and treated observations
sel <- c(mout1_lim$index.treated, mout1_lim$index.control)
# Create dataset of matches
GM_low_11_18 <- match1_lim[sel,]
# Add weights
GM_low_11_18$w <- c(mout1_lim$weights, mout1_lim$weights)

##  GM + WLS with bias adjustment
names(GM_low_11_18)

# Formula for regressions with limited covariate dataset
f_GM_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_low_11_18)[7:21], collapse = " + "), 
                                     " + factor(prov)")))

m_GM_low_11_18 <- lm(f_GM_lim, data = GM_low_11_18, weights = w)


## Supreme Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out2_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + factor(prov), 
                   family = binomial(link = "probit"), data = rizzo2_11_18)
e <- fitted(ps.out2_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match2_lim <- data.frame(model.matrix(ps.out2_lim))
names(match2_lim)
  # Remove intercept and prov
match2_lim <- match2_lim[,-c(1, 18:29)]
names(match2_lim)
  # Add linearized estimated propensity scores
match2_lim$l <- l
names(match2_lim)
  # Add in other variables
match2_lim <- cbind("trustbi" = rizzo2_11_18$trustbi, 
                    "Tr" = rizzo2_11_18$Tr, 
                    "city" = rizzo2_11_18$city, # City (clustered SEs and city FE)
                    "date" = rizzo2_11_18$date, # Date of interview (clustered SEs)
                    "prov" = rizzo2_11_18$prov, # Province (province FE)
                    match2_lim, 
                    "trustord" = rizzo2_11_18$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo2_11_18$trust)  # scaled outcome (appendix analysis))
names(match2_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 35 minutes
  # Solution Found Generation 34
  # Number of Generations Run 85
set.seed(1)
gm.out2_lim <-	GenMatch(Tr = match2_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match2_lim[, c(6:22)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out2_lim, file = "genetic-matching-output/gen-match-output-supreme-lim-11-18-respondents.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-supreme-lim-11-18-respondents.RData")

names(match2_lim)

# Use Match() to obtain dataset of matched observations
mout2_lim <- Match(Y = match2_lim$trustbi, 
                   Tr = match2_lim$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match2_lim[, c(6:22)], 
                   Weight.matrix = gm.out2_lim,
                   BiasAdjust = T,
                   ties=T,
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_lim$index.treated, mout2_lim$index.control)
# Create dataset of matches
GM_sup_11_18 <- match2_lim[sel,]
# Add weights
GM_sup_11_18$w <- c(mout2_lim$weights, mout2_lim$weights)

##  GM + WLS with bias adjustment
m_GM_sup_11_18 <- lm(f_GM_lim, data = GM_sup_11_18, weights = w)

### Save models for tables and figure
GM_11_18 <- list("GM_lower_11_18" = m_GM_low_11_18, "GM_supreme_11_18" = m_GM_sup_11_18, 
               "GM_low_11_18" = GM_low_11_18, "GM_sup_11_18" = GM_sup_11_18)
save(GM_11_18, file = "models/GM-limited-covariates-11-18-respondents.RData")


### Prepare table

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call models
load("models/OLS-limited-covariates-11-18-respondents.RData")
load("models/EB-limited-covariates-11-18-respondents.RData")
load("models/GM-limited-covariates-11-18-respondents.RData")

names(OLS_11_18)
names(EB_11_18)
names(GM_11_18)

# Lower Court models (limited set of covariates)
m1 <- OLS_11_18[["OLS_lower_11_18"]] # OLS model
rizzo1_11_18 <- OLS_11_18[["rizzo1_11_18"]] # OLS dataset
m2 <- EB_11_18[["EB_lower_11_18"]] # EB model
EB_low_11_18 <- EB_11_18[["EB_low_11_18"]] # EB dataset
m3 <- GM_11_18[["GM_lower_11_18"]] # GM model
GM_low_11_18 <- GM_11_18[["GM_low_11_18"]] # GM dataset

# Supreme Court models (limited set of covariates)
m4 <- OLS_11_18[["OLS_supreme_11_18"]] # OLS model
rizzo2_11_18 <- OLS_11_18[["rizzo2_11_18"]] # OLS dataset
m5 <- EB_11_18[["EB_supreme_11_18"]] # EB model
EB_sup_11_18 <- EB_11_18[["EB_sup_11_18"]] # EB dataset
m6 <- GM_11_18[["GM_supreme_11_18"]] # GM model
GM_sup_11_18 <- GM_11_18[["GM_sup_11_18"]] # GM dataset

## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = ~ city + date, type = "HC1"))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = ~ city + date, type = "HC1"))[,2]
se3 <- coeftest(m3, vcovCL(m3, cluster = ~ city + date, type = "HC1"))[,2]
se4 <- coeftest(m4, vcovCL(m4, cluster = ~ city + date, type = "HC1"))[,2]
se5 <- coeftest(m5, vcovCL(m5, cluster = ~ city + date, type = "HC1"))[,2]
# vcovCL doesn't compute some SEs (NaN), so use feols() from the fixest package
f_GM_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", paste0(paste0(names(GM_sup_11_18)[7:21], collapse = " + "), 
                                     " + factor(prov)")))
se6 <- feols(f_GM_lim, cluster = ~city+date, data = GM_sup_11_18)[["se"]]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1$resid + m1$fitted.values), 
                 mean(m2$resid + m2$fitted.values),
                 mean(m3$resid + m3$fitted.values),
                 mean(m4$resid + m4$fitted.values),
                 mean(m5$resid + m5$fitted.values),
                 mean(m6$resid + m6$fitted.values)),3)
Y_sd <- round(c(sd(m1$resid + m1$fitted.values), 
                sd(m2$resid + m2$fitted.values),
                sd(m3$resid + m3$fitted.values),
                sd(m4$resid + m4$fitted.values),
                sd(m5$resid + m5$fitted.values),
                sd(m6$resid + m6$fitted.values)),3)


### Create table
tab_11_18 <- stargazer(m1, m2, m3, m4, m5, m6,
                        se=list(se1, se2, se3, se4, se5, se6),
                        title="Removing June 11\\textsuperscript{th} and June 18\\textsuperscript{th} Respondents", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:11_18",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("Tr", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                         c("sd(Trust)", Y_sd),
                                         c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("Province FE?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"))
                       )
# Format table for publication
tab_11_18
tab_11_18 <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub("\\hline \\\\[-1.8ex] ", "", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub("\\hline ", "\\bottomrule", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub("[-1.8ex] ", "", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub("  \\label{tab:11_18} ", 
                   "\\tabcolsep=8pt  \\label{tab:11_18}  \\resizebox{\\linewidth}{!}{%", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub("\\end{tabular} ", "\\end{tabular} }", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                   "\\begin{tabular}{l*{6}{d{1.3}}}", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                   " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", tab_11_18, fixed=TRUE)
tab_11_18 <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                   "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", tab_11_18, fixed=TRUE)

sink("tab/removing-11-18.tex")
cat(tab_11_18, sep="\n")
sink()


###########################################
# Appendix: Table F5 (Only Cities with Respondents in All Conditions)

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Limited set of covariates
sel_lim <-	!is.na(rizzo$Tr) &
  !is.na(rizzo$party2) &
  !is.na(rizzo$age) &
  !is.na(rizzo$trustbi) &
  !is.na(rizzo$female) &
  !is.na(rizzo$education) &
  !is.na(rizzo$SES_ord) &
  !is.na(rizzo$subinc_ord) &
  !is.na(rizzo$class_ord) &
  !is.na(rizzo$religion) &
  !is.na(rizzo$city)

table(sel_lim)
rizzo_limited <- rizzo[sel_lim,]
dim(rizzo_limited)

# Cities with variation
table(rizzo_limited$city, rizzo_limited$Tr)

sel_cities <- which(rizzo_limited$city %in% c("Capital Federal-Ciudad de Buenos Aires",
                                              "Mendoza-Gran Mendoza", 
                                              "Chaco-Gran Resistencia",
                                              "Entre Rios-Gualeguay", 
                                              "Tucuman-Gran San Miguel de Tucuman", 
                                              "Buenos Aires-Gran Buenos Aires",
                                              "Santa Fe-Gran Rosario", 
                                              "Neuquen-Neuquen"))
## Limited data set
rizzo_cities <- rizzo_limited[sel_cities,]
dim(rizzo_cities)

# Collapse categories of religion due to lack of variation
table(rizzo_cities$religion)
levels(rizzo_cities$religion)[levels(rizzo_cities$religion) %in% c("Agnostico/Ateo/Ninguna/No answer", 
                                                                   "Otra")] <- "Otra/Agnostico/Ateo/Ninguna/No answer"
table(rizzo_cities$religion)

rizzo1_cities <- rizzo_cities[rizzo_cities$Tr != 2, ]
rizzo2_cities <- rizzo_cities[rizzo_cities$Tr != 1, ]
rizzo2_cities$Tr <- ifelse(rizzo2_cities$Tr == 2, 1, 0)


### OLS models 
f_OLS <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion")

## Lower court
m_OLS_low_cities <- lm(f_OLS, data = rizzo1_cities)

## Supreme court
m_OLS_sup_cities <- lm(f_OLS, data = rizzo2_cities)

### Save models for tables and figure
OLS_cities <- list("OLS_lower_cities" = m_OLS_low_cities, "OLS_supreme_cities" = m_OLS_sup_cities, 
                   "rizzo1_cities" = rizzo1_cities, "rizzo2_cities" = rizzo2_cities)
save(OLS_cities, file = "models/OLS-limited-covariates-cities-all-conditions.RData")

###########
### Entropy balance + WLS models (binary outcome)
###########

## Lower Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_low_cities <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo1_cities))
)

colnames(EB_low_cities)

  # Remove intercept
EB_low_cities <- EB_low_cities[, -1]

colnames(EB_low_cities)

  # Add in outcomes and missing variables
EB_low_cities <- cbind("trustbi" = rizzo1_cities$trustbi, 
                 "city" = rizzo1_cities$city, # City (clustered SEs and city FE)
                 "date" = rizzo1_cities$date, # Date of interview (clustered SEs)
                 EB_low_cities, # Covariate matrix
                 "trustord" = rizzo1_cities$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo1_cities$trust)  # scaled outcome (appendix analysis)
names(EB_low_cities)

  # Order observations to add entropy balance weights (controls first)
EB_low_cities <- rbind(EB_low_cities[EB_low_cities$Tr == 0,], 
                      EB_low_cities[EB_low_cities$Tr == 1,])

colnames(EB_low_cities)

# Compute entropy balance (EB) weights
out1_lim <- ebalance(Treatment = EB_low_cities$Tr, 
                     X = EB_low_cities[,5:19]) # include only covariates to balance on

# Add weights to (ordered) dataset
EB_low_cities$w <- c(out1_lim$w, # weights for control observations 
                  rep(1, nrow(EB_low_cities[EB_low_cities$Tr == 1,])))

# Check distribution of weights
hist(out1_lim$w, 100) # weights are well behaved

names(EB_low_cities)

# Formula for regressions with limited covariate dataset
names(EB_low_cities)
f_EB_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                       paste0(paste0(names(EB_low_cities)[6:19], collapse = " + "))))

# WLS with bias adjustment
m_EB_low_cities <- lm(f_EB_lim, data = EB_low_cities, weights = w)


## Supreme Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_sup_cities <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_cities))
)

colnames(EB_sup_cities)

  # Remove intercept
EB_sup_cities <- EB_sup_cities[, -1]

colnames(EB_sup_cities)

  # Add in outcomes and missing variables
EB_sup_cities <- cbind("trustbi" = rizzo2_cities$trustbi, 
                 "city" = rizzo2_cities$city, # City (clustered SEs and city FE)
                 "date" = rizzo2_cities$date, # Date of interview (clustered SEs)
                 EB_sup_cities, # Covariate matrix
                 "trustord" = rizzo2_cities$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo2_cities$trust)  # scaled outcome (appendix analysis)
names(EB_sup_cities)

  # Order observations to add entropy balance weights (controls first)
EB_sup_cities <- rbind(EB_sup_cities[EB_sup_cities$Tr == 0,], 
                      EB_sup_cities[EB_sup_cities$Tr == 1,])

colnames(EB_sup_cities)

# Compute entropy balance (EB) weights
out2_lim <- ebalance(Treatment = EB_sup_cities$Tr, 
                     X = EB_sup_cities[,5:19]) # include only covariates to balance on

# Check distribution of weights
hist(out2_lim$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_sup_cities$w <- c(out2_lim$w, # weights for control observations 
                  rep(1, nrow(EB_sup_cities[EB_sup_cities$Tr == 1,])))

# WLS with bias adjustment
m_EB_sup_cities <- lm(f_EB_lim, data = EB_sup_cities, weights = w)


### Save models for tables and figure
EB_cities <- list("EB_lower_cities" = m_EB_low_cities, "EB_supreme_cities" = m_EB_sup_cities, 
                "EB_low_cities" = EB_low_cities, "EB_sup_cities" = EB_sup_cities)
save(EB_cities, file = "models/EB-limited-covariates-cities-all-conditions.RData")


###########
### Genetic matching + WLS models (binary outcome)
###########

## Lower Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out1_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion, 
                   family = binomial(link = "probit"), data = rizzo1_cities)
e <- fitted(ps.out1_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match1_lim <- data.frame(model.matrix(ps.out1_lim))
names(match1_lim)
  # Remove intercept
match1_lim <- match1_lim[,-1]
names(match1_lim)
  # Add linearized estimated propensity scores
match1_lim$l <- l
names(match1_lim)
  # Add in other variables
match1_lim <- cbind("trustbi" = rizzo1_cities$trustbi, 
                    "Tr" = rizzo1_cities$Tr, 
                    "city" = rizzo1_cities$city, # City (clustered SEs and city FE)
                    "date" = rizzo1_cities$date, # Date of interview (clustered SEs)
                    match1_lim, 
                    "trustord" = rizzo1_cities$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo1_cities$trust)  # scaled outcome (appendix analysis))
names(match1_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores) 

# Computation takes about 20 minutes
  # Solution Found Generation 6
  # Number of Generations Run 57
set.seed(1)
gm.out1_lim <-	GenMatch(Tr = match1_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match1_lim[, c(5:20)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out1_lim, file = "genetic-matching-output/gen-match-output-lower-lim-cities-all-conditions.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-lower-lim-cities-all-conditions.RData")

names(match1_lim)

# Use Match() to obtain dataset of matched observations
mout1_lim <- Match(Y = match1_lim$trustbi, 
                  Tr = match1_lim$Tr, 
                  # Include only covariates (and linearized estimated propensity scores)
                  X = match1_lim[, c(5:20)], 
                  Weight.matrix = gm.out1_lim,
                  BiasAdjust = T,
                  ties=T, 
                  replace=T)

# Vectors of matched control and treated observations
sel <- c(mout1_lim$index.treated, mout1_lim$index.control)
# Create dataset of matches
GM_low_cities <- match1_lim[sel,]
# Add weights
GM_low_cities$w <- c(mout1_lim$weights, mout1_lim$weights)

##  GM + WLS with bias adjustment
names(GM_low_cities)

# Formula for regressions with limited covariate dataset
f_GM_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_low_cities)[6:19], collapse = " + "))))

m_GM_low_cities <- lm(f_GM_lim, data = GM_low_cities, weights = w)


## Supreme Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out2_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion, 
                   family = binomial(link = "probit"), data = rizzo2_cities)
e <- fitted(ps.out2_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match2_lim <- data.frame(model.matrix(ps.out2_lim))
names(match2_lim)
  # Remove intercept
match2_lim <- match2_lim[,-1]
names(match2_lim)
  # Add linearized estimated propensity scores
match2_lim$l <- l
names(match2_lim)
  # Add in other variables
match2_lim <- cbind("trustbi" = rizzo2_cities$trustbi, 
                    "Tr" = rizzo2_cities$Tr, 
                    "city" = rizzo2_cities$city, # City (clustered SEs and city FE)
                    "date" = rizzo2_cities$date, # Date of interview (clustered SEs)
                    match2_lim, 
                    "trustord" = rizzo2_cities$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo2_cities$trust)  # scaled outcome (appendix analysis))
names(match2_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 30 minutes
  # Solution Found Generation 30
  # Number of Generations Run 81
set.seed(1)
gm.out2_lim <-	GenMatch(Tr = match2_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match2_lim[, c(5:20)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out2_lim, file = "genetic-matching-output/gen-match-output-supreme-lim-cities-all-conditions.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-supreme-lim-cities-all-conditions.RData")

names(match2_lim)

# Use Match() to obtain dataset of matched observations
mout2_lim <- Match(Y = match2_lim$trustbi, 
                   Tr = match2_lim$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match2_lim[, c(5:20)], 
                   Weight.matrix = gm.out2_lim,
                   BiasAdjust = T,
                   ties=T,
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_lim$index.treated, mout2_lim$index.control)
# Create dataset of matches
GM_sup_cities <- match2_lim[sel,]
# Add weights
GM_sup_cities$w <- c(mout2_lim$weights, mout2_lim$weights)

##  GM + WLS with bias adjustment
m_GM_sup_cities <- lm(f_GM_lim, data = GM_sup_cities, weights = w)

### Save models for tables and figure
GM_cities <- list("GM_lower_cities" = m_GM_low_cities, "GM_supreme_cities" = m_GM_sup_cities, 
               "GM_low_cities" = GM_low_cities, "GM_sup_cities" = GM_sup_cities)
save(GM_cities, file = "models/GM-limited-covariates-cities-all-conditions.RData")

### Prepare table

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call models
load("models/OLS-limited-covariates-cities-all-conditions.RData")
load("models/EB-limited-covariates-cities-all-conditions.RData")
load("models/GM-limited-covariates-cities-all-conditions.RData")

names(OLS_cities)
names(EB_cities)
names(GM_cities)

# Lower Court models (limited set of covariates)
m1 <- OLS_cities[["OLS_lower_cities"]] # OLS model
rizzo1_cities <- OLS_cities[["rizzo1_cities"]] # OLS dataset
m2 <- EB_cities[["EB_lower_cities"]] # EB model
EB_low_cities <- EB_cities[["EB_low_cities"]] # EB dataset
m3 <- GM_cities[["GM_lower_cities"]] # GM model
GM_low_cities <- GM_cities[["GM_low_cities"]] # GM dataset

# Supreme Court models (limited set of covariates)
m4 <- OLS_cities[["OLS_supreme_cities"]] # OLS model
rizzo2_cities <- OLS_cities[["rizzo2_cities"]] # OLS dataset
m5 <- EB_cities[["EB_supreme_cities"]] # EB model
EB_sup_cities <- EB_cities[["EB_sup_cities"]] # EB dataset
m6 <- GM_cities[["GM_supreme_cities"]] # GM model
GM_sup_cities <- GM_cities[["GM_sup_cities"]] # GM dataset

## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = ~ city + date, type = "HC1"))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = ~ city + date, type = "HC1"))[,2]
se3 <- coeftest(m3, vcovCL(m3, cluster = ~ city + date, type = "HC1"))[,2]
se4 <- coeftest(m4, vcovCL(m4, cluster = ~ city + date, type = "HC1"))[,2]
se5 <- coeftest(m5, vcovCL(m5, cluster = ~ city + date, type = "HC1"))[,2]
se6 <- coeftest(m6, vcovCL(m6, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1$resid + m1$fitted.values), 
                 mean(m2$resid + m2$fitted.values),
                 mean(m3$resid + m3$fitted.values),
                 mean(m4$resid + m4$fitted.values),
                 mean(m5$resid + m5$fitted.values),
                 mean(m6$resid + m6$fitted.values)),3)
Y_sd <- round(c(sd(m1$resid + m1$fitted.values), 
                sd(m2$resid + m2$fitted.values),
                sd(m3$resid + m3$fitted.values),
                sd(m4$resid + m4$fitted.values),
                sd(m5$resid + m5$fitted.values),
                sd(m6$resid + m6$fitted.values)),3)


tab_cities <- stargazer(m1, m2, m3, m4, m5, m6,
                        se=list(se1, se2, se3, se4, se5, se6),
                        title="Only Cities with Respondents in All Conditions", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:cities-all-conditions",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("Tr", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                         c("sd(Trust)", Y_sd),
                                         c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("Province FE?",
                                           "", 
                                           "",
                                           "",
                                           "",
                                           "", 
                                           ""))
                        )
# Format table for publication
tab_cities
tab_cities <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", tab_cities, fixed=TRUE)
tab_cities <- gsub("\\hline \\\\[-1.8ex] ", "", tab_cities, fixed=TRUE)
tab_cities <- gsub("\\hline ", "\\bottomrule", tab_cities, fixed=TRUE)
tab_cities <- gsub("[-1.8ex] ", "", tab_cities, fixed=TRUE)
tab_cities <- gsub("  \\label{tab:cities-all-conditions} ", 
                   "\\tabcolsep=8pt  \\label{tab:cities-all-conditions}  \\resizebox{\\linewidth}{!}{%", tab_cities, fixed=TRUE)
tab_cities <- gsub("\\end{tabular} ", "\\end{tabular} }", tab_cities, fixed=TRUE)
tab_cities <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                   "\\begin{tabular}{l*{6}{d{1.3}}}", tab_cities, fixed=TRUE)
tab_cities <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                   " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", tab_cities, fixed=TRUE)
tab_cities <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                   "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", tab_cities, fixed=TRUE)

sink("tab/cities-all-conditions.tex")
cat(tab_cities, sep="\n")
sink()


###########################################
# Appendix: Table F6.1 (Only cities with respondents in all conditions by court model)

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Limited set of covariates
sel_lim <-	!is.na(rizzo$Tr) &
  !is.na(rizzo$party2) &
  !is.na(rizzo$age) &
  !is.na(rizzo$trustbi) &
  !is.na(rizzo$female) &
  !is.na(rizzo$education) &
  !is.na(rizzo$SES_ord) &
  !is.na(rizzo$subinc_ord) &
  !is.na(rizzo$class_ord) &
  !is.na(rizzo$religion) &
  !is.na(rizzo$city)

table(sel_lim)
rizzo_limited <- rizzo[sel_lim,]
dim(rizzo_limited)

rizzo1_lim <- rizzo_limited[rizzo_limited$Tr != 2, ]
rizzo2_lim <- rizzo_limited[rizzo_limited$Tr != 1, ]
rizzo2_lim$Tr <- ifelse(rizzo2_lim$Tr == 2, 1, 0)

## Cities with variation
# Lower court model
table(rizzo1_lim$city, rizzo1_lim$Tr)
sel1 <- which(rizzo1_lim$city %in% c("Capital Federal-Ciudad de Buenos Aires",
                                     "Mendoza-Gran Mendoza", 
                                     "Chaco-Gran Resistencia",
                                     "Entre Rios-Gualeguay", 
                                     "Tucuman-Gran San Miguel de Tucuman", 
                                     "Buenos Aires-Gran Buenos Aires",
                                     "Santa Fe-Gran Rosario",
                                     "Santa Fe-Rafaela",
                                     "Neuquen-Neuquen"))
# Supreme court model
table(rizzo2_lim$city, rizzo2_lim$Tr)
sel2 <- which(rizzo2_lim$city %in% c("Capital Federal-Ciudad de Buenos Aires",
                                     "Mendoza-Gran Mendoza", 
                                     "Chaco-Gran Resistencia",
                                     "Entre Rios-Gualeguay", 
                                     "Tucuman-Gran San Miguel de Tucuman", 
                                     "Buenos Aires-Gran Buenos Aires",
                                     "Cordoba-Gran Cordoba",
                                     "Cordoba-Rio Tercero",
                                     "Santa Fe-Gran Rosario",
                                     "Neuquen-Neuquen"))
## Limited data set
rizzo1_cities_court <- rizzo1_lim[sel1, ]
rizzo2_cities_court <- rizzo2_lim[sel2, ]

# Collapse categories of religion due to lack of variation
table(rizzo1_cities_court$religion)
levels(rizzo1_cities_court$religion)[levels(rizzo1_cities_court$religion) %in% c("Agnostico/Ateo/Ninguna/No answer", 
                                                                                 "Otra")] <- "Otra/Agnostico/Ateo/Ninguna/No answer"
table(rizzo1_cities_court$religion)

table(rizzo2_cities_court$religion)
levels(rizzo2_cities_court$religion)[levels(rizzo2_cities_court$religion) %in% c("Agnostico/Ateo/Ninguna/No answer", 
                                                                                 "Otra")] <- "Otra/Agnostico/Ateo/Ninguna/No answer"
table(rizzo2_cities_court$religion)


### OLS models 
f_OLS <- as.formula("trustbi ~ Tr*party2 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion")

## Lower court
m_OLS_low_cities_court <- lm(f_OLS, data = rizzo1_cities_court)

## Supreme court
m_OLS_sup_cities_court <- lm(f_OLS, data = rizzo2_cities_court)

### Save models for tables and figure
OLS_cities_court <- list("OLS_lower_cities_court" = m_OLS_low_cities_court, "OLS_supreme_cities_court" = m_OLS_sup_cities_court, 
                   "rizzo1_cities_court" = rizzo1_cities_court, "rizzo2_cities_court" = rizzo2_cities_court)
save(OLS_cities_court, file = "models/OLS-limited-covariates-cities-all-conditions-by-court.RData")

###########
### Entropy balance + WLS models (binary outcome)
###########

## Lower Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_low_cities_court <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo1_cities_court))
)

colnames(EB_low_cities_court)

  # Remove intercept
EB_low_cities_court <- EB_low_cities_court[, -1]

colnames(EB_low_cities_court)

  # Add in outcomes and missing variables
EB_low_cities_court <- cbind("trustbi" = rizzo1_cities_court$trustbi, 
                 "city" = rizzo1_cities_court$city, # City (clustered SEs and city FE)
                 "date" = rizzo1_cities_court$date, # Date of interview (clustered SEs)
                 EB_low_cities_court, # Covariate matrix
                 "trustord" = rizzo1_cities_court$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo1_cities_court$trust)  # scaled outcome (appendix analysis)
names(EB_low_cities_court)

  # Order observations to add entropy balance weights (controls first)
EB_low_cities_court <- rbind(EB_low_cities_court[EB_low_cities_court$Tr == 0,], 
                      EB_low_cities_court[EB_low_cities_court$Tr == 1,])

colnames(EB_low_cities_court)

# Compute entropy balance (EB) weights
out1_lim <- ebalance(Treatment = EB_low_cities_court$Tr, 
                     X = EB_low_cities_court[,5:19]) # include only covariates to balance on

# Add weights to (ordered) dataset
EB_low_cities_court$w <- c(out1_lim$w, # weights for control observations 
                  rep(1, nrow(EB_low_cities_court[EB_low_cities_court$Tr == 1,])))

# Check distribution of weights
hist(out1_lim$w, 100) # weights are well behaved

names(EB_low_cities_court)

# Formula for regressions with limited covariate dataset
names(EB_low_cities_court)
f_EB_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                       paste0(paste0(names(EB_low_cities_court)[6:19], collapse = " + "))))

# WLS with bias adjustment
m_EB_low_cities_court <- lm(f_EB_lim, data = EB_low_cities_court, weights = w)


## Supreme Court
  # Prepare covariate matrix for ebal() function
    # ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
  # Get covariate matrix
EB_sup_cities_court <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_cities_court))
)

colnames(EB_sup_cities_court)

  # Remove intercept
EB_sup_cities_court <- EB_sup_cities_court[, -1]

colnames(EB_sup_cities_court)

  # Add in outcomes and missing variables
EB_sup_cities_court <- cbind("trustbi" = rizzo2_cities_court$trustbi, 
                 "city" = rizzo2_cities_court$city, # City (clustered SEs and city FE)
                 "date" = rizzo2_cities_court$date, # Date of interview (clustered SEs)
                 EB_sup_cities_court, # Covariate matrix
                 "trustord" = rizzo2_cities_court$trustord, # ordinal outcome (appendix analysis)
                 "trust" = rizzo2_cities_court$trust)  # scaled outcome (appendix analysis)
names(EB_sup_cities_court)

  # Order observations to add entropy balance weights (controls first)
EB_sup_cities_court <- rbind(EB_sup_cities_court[EB_sup_cities_court$Tr == 0,], 
                      EB_sup_cities_court[EB_sup_cities_court$Tr == 1,])

colnames(EB_sup_cities_court)

# Compute entropy balance (EB) weights
out2_lim <- ebalance(Treatment = EB_sup_cities_court$Tr, 
                     X = EB_sup_cities_court[,5:19]) # include only covariates to balance on

# Check distribution of weights
hist(out2_lim$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_sup_cities_court$w <- c(out2_lim$w, # weights for control observations 
                  rep(1, nrow(EB_sup_cities_court[EB_sup_cities_court$Tr == 1,])))

# WLS with bias adjustment
m_EB_sup_cities_court <- lm(f_EB_lim, data = EB_sup_cities_court, weights = w)


### Save models for tables and figure
EB_cities_court <- list("EB_lower_cities_court" = m_EB_low_cities_court, "EB_supreme_cities_court" = m_EB_sup_cities_court, 
                "EB_low_cities_court" = EB_low_cities_court, "EB_sup_cities_court" = EB_sup_cities_court)
save(EB_cities_court, file = "models/EB-limited-covariates-cities-all-conditions-by-court.RData")


###########
### Genetic matching + WLS models (binary outcome)
###########

## Lower Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out1_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion, 
                   family = binomial(link = "probit"), data = rizzo1_cities_court)
e <- fitted(ps.out1_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match1_lim <- data.frame(model.matrix(ps.out1_lim))
names(match1_lim)
  # Remove intercept
match1_lim <- match1_lim[,-1]
names(match1_lim)
  # Add linearized estimated propensity scores
match1_lim$l <- l
names(match1_lim)
  # Add in other variables
match1_lim <- cbind("trustbi" = rizzo1_cities_court$trustbi, 
                    "Tr" = rizzo1_cities_court$Tr, 
                    "city" = rizzo1_cities_court$city, # City (clustered SEs and city FE)
                    "date" = rizzo1_cities_court$date, # Date of interview (clustered SEs)
                    match1_lim, 
                    "trustord" = rizzo1_cities_court$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo1_cities_court$trust)  # scaled outcome (appendix analysis))
names(match1_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores) 

# Computation takes about 70 minutes
  # Solution Found Generation 104
  # Number of Generations Run 155
set.seed(1)
gm.out1_lim <-	GenMatch(Tr = match1_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match1_lim[, c(5:20)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out1_lim, file = "genetic-matching-output/gen-match-output-lower-lim-cities-all-conditions-by-court.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-lower-lim-cities-all-conditions-by-court.RData")

names(match1_lim)

# Use Match() to obtain dataset of matched observations
mout1_lim <- Match(Y = match1_lim$trustbi, 
                  Tr = match1_lim$Tr, 
                  # Include only covariates (and linearized estimated propensity scores)
                  X = match1_lim[, c(5:20)], 
                  Weight.matrix = gm.out1_lim,
                  BiasAdjust = T,
                  ties=T, 
                  replace=T)

# Vectors of matched control and treated observations
sel <- c(mout1_lim$index.treated, mout1_lim$index.control)
# Create dataset of matches
GM_low_cities_court <- match1_lim[sel,]
# Add weights
GM_low_cities_court$w <- c(mout1_lim$weights, mout1_lim$weights)

##  GM + WLS with bias adjustment
names(GM_low_cities_court)

# Formula for regressions with limited covariate dataset
f_GM_lim <- as.formula(paste0("trustbi ~ Tr*party2 + ", 
                              paste0(paste0(names(GM_low_cities_court)[6:19], collapse = " + "))))

m_GM_low_cities_court <- lm(f_GM_lim, data = GM_low_cities_court, weights = w)


## Supreme Court

# Prepare covariate matrix for genMatch() function
  # Compute linearized estimated propensity scores
ps.out2_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion, 
                   family = binomial(link = "probit"), data = rizzo2_cities_court)
e <- fitted(ps.out2_lim, type = "response")
l <- log(e/(1-e))

  # Get covariate matrix
match2_lim <- data.frame(model.matrix(ps.out2_lim))
names(match2_lim)
  # Remove intercept
match2_lim <- match2_lim[,-1]
names(match2_lim)
  # Add linearized estimated propensity scores
match2_lim$l <- l
names(match2_lim)
  # Add in other variables
match2_lim <- cbind("trustbi" = rizzo2_cities_court$trustbi, 
                    "Tr" = rizzo2_cities_court$Tr, 
                    "city" = rizzo2_cities_court$city, # City (clustered SEs and city FE)
                    "date" = rizzo2_cities_court$date, # Date of interview (clustered SEs)
                    match2_lim, 
                    "trustord" = rizzo2_cities_court$trustord, # ordinal outcome (appendix analysis)
                    "trust" = rizzo2_cities_court$trust)  # scaled outcome (appendix analysis))
names(match2_lim)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 35 minutes
  # Solution Found Generation 37
  # Number of Generations Run 88
set.seed(1)
gm.out2_lim <-	GenMatch(Tr = match2_lim$Tr, 
                # Include only covariates (and linearized estimated propensity scores)
                X = match2_lim[, c(5:20)], 
                pop.size = 5000,
                wait.generations = 50, 
                cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out2_lim, file = "genetic-matching-output/gen-match-output-supreme-lim-cities-all-conditions-by-court.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-supreme-lim-cities-all-conditions-by-court.RData")

names(match2_lim)

# Use Match() to obtain dataset of matched observations
mout2_lim <- Match(Y = match2_lim$trustbi, 
                   Tr = match2_lim$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match2_lim[, c(5:20)], 
                   Weight.matrix = gm.out2_lim,
                   BiasAdjust = T,
                   ties=T,
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_lim$index.treated, mout2_lim$index.control)
# Create dataset of matches
GM_sup_cities_court <- match2_lim[sel,]
# Add weights
GM_sup_cities_court$w <- c(mout2_lim$weights, mout2_lim$weights)

##  GM + WLS with bias adjustment
m_GM_sup_cities_court <- lm(f_GM_lim, data = GM_sup_cities_court, weights = w)

### Save models for tables and figure
GM_cities_court <- list("GM_lower_cities_court" = m_GM_low_cities_court, "GM_supreme_cities_court" = m_GM_sup_cities_court, 
               "GM_low_cities_court" = GM_low_cities_court, "GM_sup_cities_court" = GM_sup_cities_court)
save(GM_cities_court, file = "models/GM-limited-covariates-cities-all-conditions-by-court.RData")


### Prepare table

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call models
load("models/OLS-limited-covariates-cities-all-conditions-by-court.RData")
load("models/EB-limited-covariates-cities-all-conditions-by-court.RData")
load("models/GM-limited-covariates-cities-all-conditions-by-court.RData")

names(OLS_cities_court)
names(EB_cities_court)
names(GM_cities_court)

# Lower Court models (limited set of covariates)
m1 <- OLS_cities_court[["OLS_lower_cities_court"]] # OLS model
rizzo1_cities_court <- OLS_cities_court[["rizzo1_cities_court"]] # OLS dataset
m2 <- EB_cities_court[["EB_lower_cities_court"]] # EB model
EB_low_cities_court <- EB_cities_court[["EB_low_cities_court"]] # EB dataset
m3 <- GM_cities_court[["GM_lower_cities_court"]] # GM model
GM_low_cities_court <- GM_cities_court[["GM_low_cities_court"]] # GM dataset

# Supreme Court models (limited set of covariates)
m4 <- OLS_cities_court[["OLS_supreme_cities_court"]] # OLS model
rizzo2_cities_court <- OLS_cities_court[["rizzo2_cities_court"]] # OLS dataset
m5 <- EB_cities_court[["EB_supreme_cities_court"]] # EB model
EB_sup_cities_court <- EB_cities_court[["EB_sup_cities_court"]] # EB dataset
m6 <- GM_cities_court[["GM_supreme_cities_court"]] # GM model
GM_sup_cities_court <- GM_cities_court[["GM_sup_cities_court"]] # GM dataset

## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = ~ city + date, type = "HC1"))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = ~ city + date, type = "HC1"))[,2]
se3 <- coeftest(m3, vcovCL(m3, cluster = ~ city + date, type = "HC1"))[,2]
se4 <- coeftest(m4, vcovCL(m4, cluster = ~ city + date, type = "HC1"))[,2]
se5 <- coeftest(m5, vcovCL(m5, cluster = ~ city + date, type = "HC1"))[,2]
se6 <- coeftest(m6, vcovCL(m6, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1$resid + m1$fitted.values), 
                 mean(m2$resid + m2$fitted.values),
                 mean(m3$resid + m3$fitted.values),
                 mean(m4$resid + m4$fitted.values),
                 mean(m5$resid + m5$fitted.values),
                 mean(m6$resid + m6$fitted.values)),3)
Y_sd <- round(c(sd(m1$resid + m1$fitted.values), 
                sd(m2$resid + m2$fitted.values),
                sd(m3$resid + m3$fitted.values),
                sd(m4$resid + m4$fitted.values),
                sd(m5$resid + m5$fitted.values),
                sd(m6$resid + m6$fitted.values)),3)


tab_cities_court <- stargazer(m1, m2, m3, m4, m5, m6,
                        se=list(se1, se2, se3, se4, se5, se6),
                        title="Only Cities with Respondents in All Conditions by Court Model", align=TRUE,
                        dep.var.labels.include = FALSE, 
                        dep.var.caption = "",
                        label = "tab:cities-all-conditions-by-court",
                        column.labels = c("\\textbf{Lower Court}",
                                          "\\textbf{Supreme Court}"),
                        column.separate = c(3, 3),
                        keep = c("Tr", "party2", "Constant"),
                        covariate.labels = c("Court Ruling","Government Supporter", 
                                             "C. Ruling $\\times$ Gov. Supporter"),
                        star.char = c("+", "*", "**", "***"),
                        star.cutoffs = c(.1, .05, .01, .001),
                        notes.append=FALSE, notes.align = "l", notes.label = "",
                        omit.stat=c("f", "ser", "rsq"),
                        header = FALSE,
                        no.space = TRUE,
                        notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                        table.placement = "H",
                        add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                         c("sd(Trust)", Y_sd),
                                         c("\\midrule Controls?",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}",
                                           "\\multicolumn{1}{c}{\\checkmark}", 
                                           "\\multicolumn{1}{c}{\\checkmark}"),
                                         c("Province FE?",
                                           "", 
                                           "",
                                           "",
                                           "",
                                           "", 
                                           ""))
)
# Format table for publication
tab_cities_court
tab_cities_court <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub("\\hline \\\\[-1.8ex] ", "", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub("\\hline ", "\\bottomrule", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub("[-1.8ex] ", "", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub("  \\label{tab:cities-all-conditions-by-court} ", 
                   "\\tabcolsep=8pt  \\label{tab:cities-all-conditions-by-court}  \\resizebox{\\linewidth}{!}{%", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub("\\end{tabular} ", "\\end{tabular} }", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                   "\\begin{tabular}{l*{6}{d{1.3}}}", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
                   " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", tab_cities_court, fixed=TRUE)
tab_cities_court <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
                   "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", tab_cities_court, fixed=TRUE)

sink("tab/cities-all-conditions-by-court.tex")
cat(tab_cities_court, sep="\n")
sink()


#################################################
#### Time Trends
#### Appendix: tables G1.1 and G1.2 ####
#################################################

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

###########################################
# Appendix: Table G1.1 (Time Trends in Control Group Subsample)

rizzo1_tt <- rizzo1_lim
rizzo2_tt <- rizzo2_lim

##  create time trend variable
rizzo1_tt$dtime <- as.numeric(difftime(rizzo1_tt$date_full, as.Date("2013-06-1"), units = "days"))
rizzo2_tt$dtime <- as.numeric(difftime(rizzo2_tt$date_full, as.Date("2013-06-1"), units = "days"))
table(rizzo1_tt$dtime)
table(rizzo2_tt$dtime)

## Time trends in Co group
control_subsample <- rizzo1_tt[rizzo1_tt$Tr == 0, ]

# Model 1: daily trends
tt1 <- lm(trustbi ~ dtime, data = control_subsample)
se1 <- coeftest(tt1, vcov = vcovCL(tt1, cluster = ~ city + date, type = "HC1"))[,2]

## Split control subsample at median and then test for effect
control_subsample$placebo_Tr <- ifelse(control_subsample$date < median(control_subsample$date), 
                                       0, 1)
table(control_subsample$placebo_Tr)

# Model 2: Placebo Tr indicator
tt2 <- lm(trustbi ~ placebo_Tr, data = control_subsample)
se2 <- coeftest(tt2, vcov = vcovCL(tt2, cluster = ~ city + date, type = "HC1"))[,2]

# Model 3: Placebo Tr indicator + controls
tt3 <- lm(trustbi ~ placebo_Tr + party2 + age + female + education + 
            SES_ord + subinc_ord + class_ord + religion, 
          data = control_subsample)
se3 <- coeftest(tt3, vcov = vcovCL(tt3, cluster = ~ city + date, type = "HC1"))[,2]

# Model 3: Placebo Tr indicator with partisanship interaction + controls
tt4 <- lm(trustbi ~ placebo_Tr*party2 + age + female + education + 
            SES_ord + subinc_ord + class_ord + religion, 
          data = control_subsample)
se4 <- coeftest(tt4, vcov = vcovCL(tt4, cluster = ~ city + date, type = "HC1"))[,2]

control_tab <- stargazer(tt1, tt2, tt3, tt4,
                         se=list(se1, se2, se3, se4),
                         title="Time Trends in Control Group Subsample", align=TRUE,
                         dep.var.labels.include = FALSE, 
                         dep.var.caption = "",
                         label = "tab:control-time-trends",
                         keep = c("dtime", "placebo_Tr", "party2", "Constant"),
                         covariate.labels = c("Days","Placebo Tr. Indicator", 
                                              "Government Supporter", 
                                              "Placebo Tr. $\\times$ Gov. Supporter"),
                         star.char = c("+", "*", "**", "***"),
                         star.cutoffs = c(.1, .05, .01, .001),
                         notes.append=FALSE, notes.align = "l", notes.label = "",
                         omit.stat=c("f", "ser", "rsq"),
                         header = FALSE,
                         no.space = TRUE,
                         notes = c("\\small \\parbox[t]{0.8 \\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. \\textit{Days}: number of days before June 11\\textsuperscript{th} (date of the lower court ruling). \\textit{Placebo Tr. Indicator}: binary indicator split the control group subsample at its empirical median. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                         table.placement = "H", 
                         add.lines = list(c("\\midrule Controls?",
                                            "\\multicolumn{1}{c}{\\checkmark}", 
                                            "\\multicolumn{1}{c}{\\checkmark}",
                                            "\\multicolumn{1}{c}{\\checkmark}",
                                            "\\multicolumn{1}{c}{\\checkmark}",
                                            "\\multicolumn{1}{c}{\\checkmark}", 
                                            "\\multicolumn{1}{c}{\\checkmark}"),
                                          c("Province FE?",
                                            "", 
                                            "",
                                            "",
                                            "",
                                            "", 
                                            ""))
)

# Format table for publication
control_tab
control_tab <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", control_tab, fixed=TRUE)
control_tab <- gsub("\\hline \\\\[-1.8ex] ", "", control_tab, fixed=TRUE)
control_tab <- gsub("\\hline ", "\\bottomrule", control_tab, fixed=TRUE)
control_tab <- gsub("\\\\[-1.8ex] ", "", control_tab, fixed=TRUE)
control_tab <- gsub("  \\label{tab:control-time-trends} ", 
                    "\\tabcolsep=16pt  \\label{tab:control-time-trends}", control_tab, fixed=TRUE)
#control_tab <- gsub("\\end{tabular} ", "\\end{tabular} }", control_tab, fixed=TRUE)
control_tab <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
                    "\\begin{tabular}{l*{4}{d{1.3}}}", control_tab, fixed=TRUE)
control_tab <- gsub("& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)}\\\\ ", 
                    "& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)}\\\\ \\midrule", control_tab, fixed=TRUE)
#control_tab[20] <- "\\midrule"

sink("tab/control-time-trends.tex")
cat(control_tab, sep="\n")
sink()


###########################################
# Appendix: Table G1.1 (Time Trends)

###  OLS
f_OLS <- as.formula("trustbi ~ 	Tr*party2 + dtime + age + female + education + 
            SES_ord + subinc_ord + class_ord + religion + factor(prov)")
m_OLS_low_tt <- lm(f_OLS, data = rizzo1_tt)

m_OLS_sup_tt <- lm(f_OLS, data = rizzo2_tt)

### Save models
OLS_tt <- list("OLS_lower_tt" = m_OLS_low_tt, "OLS_supreme_tt" = m_OLS_sup_tt, 
               "rizzo1_tt" = rizzo1_tt, "rizzo2_tt" = rizzo2_tt)
save(OLS_tt, file = "models/OLS-limited-covariates-time-trends.RData")

###########
### Entropy balance + WLS models (binary outcome)
###########

## Lower Court
# Prepare covariate matrix for ebal() function
# ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
# Get covariate matrix
EB_low_tt <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo1_tt))
)

colnames(EB_low_tt)

# Remove intercept
EB_low_tt <- EB_low_tt[, -1]

colnames(EB_low_tt)

# Add in outcomes and missing variables
EB_low_tt <- cbind("trustbi" = rizzo1_tt$trustbi, 
                   "city" = rizzo1_tt$city, # City (clustered SEs and city FE)
                   "date" = rizzo1_tt$date, # Date of interview (clustered SEs)
                   "prov" = rizzo1_tt$prov, # Province (province FE)
                   EB_low_tt, # Covariate matrix
                   "dtime" = rizzo1_tt$dtime) # Daily time trends
names(EB_low_tt)

# Order observations to add entropy balance weights (controls first)
EB_low_tt <- rbind(EB_low_tt[EB_low_tt$Tr == 0,], 
                   EB_low_tt[EB_low_tt$Tr == 1,])

colnames(EB_low_tt)

# Compute entropy balance (EB) weights
out1_lim <- ebalance(Treatment = EB_low_tt$Tr, 
                     X = EB_low_tt[,6:21]) # include only covariates to balance on

# Add weights to (ordered) dataset
EB_low_tt$w <- c(out1_lim$w, # weights for control observations 
                 rep(1, nrow(EB_low_tt[EB_low_tt$Tr == 1,])))

# Check distribution of weights
hist(out1_lim$w, 100) # weights are well behaved

names(EB_low_tt)

# Formula for regressions with limited covariate dataset
names(EB_low_tt)
f_EB_tt <- as.formula(paste0("trustbi ~ Tr*party2 + dtime + ", 
                             paste0(paste0(names(EB_low_tt)[7:21], collapse = " + "), 
                                    " + factor(prov)")))

# WLS with bias adjustment
m_EB_low_tt <- lm(f_EB_tt, data = EB_low_tt, weights = w)


## Supreme Court
# Prepare covariate matrix for ebal() function
# ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party2 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
# Get covariate matrix
EB_sup_tt <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_tt))
)

colnames(EB_sup_tt)

# Remove intercept
EB_sup_tt <- EB_sup_tt[, -1]

colnames(EB_sup_tt)

# Add in outcomes and missing variables
EB_sup_tt <- cbind("trustbi" = rizzo2_tt$trustbi, 
                   "city" = rizzo2_tt$city, # City (clustered SEs and city FE)
                   "date" = rizzo2_tt$date, # Date of interview (clustered SEs)
                   "prov" = rizzo2_tt$prov, # Province (province FE)
                   EB_sup_tt, # Covariate matrix
                   "dtime" = rizzo2_tt$dtime) # Daily time trends
names(EB_sup_tt)

# Order observations to add entropy balance weights (controls first)
EB_sup_tt <- rbind(EB_sup_tt[EB_sup_tt$Tr == 0,], 
                   EB_sup_tt[EB_sup_tt$Tr == 1,])

colnames(EB_sup_tt)

# Compute entropy balance (EB) weights
out2_lim <- ebalance(Treatment = EB_sup_tt$Tr, 
                     X = EB_sup_tt[,6:21]) # include only covariates to balance on

# Check distribution of weights
hist(out2_lim$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_sup_tt$w <- c(out2_lim$w, # weights for control observations 
                 rep(1, nrow(EB_sup_tt[EB_sup_tt$Tr == 1,])))

# WLS with bias adjustment
m_EB_sup_tt <- lm(f_EB_tt, data = EB_sup_tt, weights = w)


### Save models for tables and figure
EB_tt <- list("EB_lower_tt" = m_EB_low_tt, "EB_supreme_tt" = m_EB_sup_tt, 
              "EB_low_tt" = EB_low_tt, "EB_sup_tt" = EB_sup_tt)
save(EB_tt, file = "models/EB-limited-covariates-time-trends.RData")


###########
### Genetic matching + WLS models (binary outcome)
###########

## Lower Court

# Prepare covariate matrix for genMatch() function
# Compute linearized estimated propensity scores
ps.out1_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + factor(prov), 
                   family = binomial(link = "probit"), data = rizzo1_tt)
e <- fitted(ps.out1_lim, type = "response")
l <- log(e/(1-e))

# Get covariate matrix
match1_lim <- data.frame(model.matrix(ps.out1_lim))
names(match1_lim)
# Remove intercept and prov
match1_lim <- match1_lim[,-c(1, 18:28)]
names(match1_lim)
# Add linearized estimated propensity scores
match1_lim$l <- l
names(match1_lim)
# Add in other variables
match1_lim <- cbind("trustbi" = rizzo1_tt$trustbi, 
                    "Tr" = rizzo1_tt$Tr, 
                    "city" = rizzo1_tt$city, # City (clustered SEs and city FE)
                    "date" = rizzo1_tt$date, # Date of interview (clustered SEs)
                    "prov" = rizzo1_tt$prov, # Province (province FE)
                    match1_lim, 
                    "dtime" = rizzo1_tt$dtime) # Daily time trends
names(match1_lim)

## load GenMatch output (previously computed)
load(file = "genetic-matching-output-stored/gen-match-output-lower-lim.RData")

names(match1_lim)

# Use Match() to obtain dataset of matched observations
mout1_lim <- Match(Y = match1_lim$trustbi, 
                   Tr = match1_lim$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match1_lim[, c(6:22)], 
                   Weight.matrix = gm.out1_lim,
                   BiasAdjust = T,
                   ties=T, 
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout1_lim$index.treated, mout1_lim$index.control)
# Create dataset of matches
GM_low_tt <- match1_lim[sel,]
# Add weights
GM_low_tt$w <- c(mout1_lim$weights, mout1_lim$weights)

##  GM + WLS with bias adjustment
names(GM_low_tt)

# Formula for regressions with limited covariate dataset
f_GM_lim <- as.formula(paste0("trustbi ~ Tr*party2 + dtime + ", 
                              paste0(paste0(names(GM_low_tt)[7:21], collapse = " + "), 
                                     " + factor(prov)")))

m_GM_low_tt <- lm(f_GM_lim, data = GM_low_tt, weights = w)


## Supreme Court

# Prepare covariate matrix for genMatch() function
# Compute linearized estimated propensity scores
ps.out2_lim <- glm(Tr ~ party2 + age + female + education + SES_ord + 
                     subinc_ord + class_ord + religion + factor(prov), 
                   family = binomial(link = "probit"), data = rizzo2_tt)
e <- fitted(ps.out2_lim, type = "response")
l <- log(e/(1-e))

# Get covariate matrix
match2_lim <- data.frame(model.matrix(ps.out2_lim))
names(match2_lim)
# Remove intercept and prov
match2_lim <- match2_lim[,-c(1, 18:29)]
names(match2_lim)
# Add linearized estimated propensity scores
match2_lim$l <- l
names(match2_lim)
# Add in other variables
match2_lim <- cbind("trustbi" = rizzo2_tt$trustbi, 
                    "Tr" = rizzo2_tt$Tr, 
                    "city" = rizzo2_tt$city, # City (clustered SEs and city FE)
                    "date" = rizzo2_tt$date, # Date of interview (clustered SEs)
                    "prov" = rizzo2_tt$prov, # Province (province FE)
                    match2_lim, 
                    "dtime" = rizzo2_tt$dtime) # Daily time trends
names(match2_lim)

## load GenMatch output (previously computed)
load(file = "genetic-matching-output-stored/gen-match-output-supreme-lim.RData")

names(match2_lim)

# Use Match() to obtain dataset of matched observations
mout2_lim <- Match(Y = match2_lim$trustbi, 
                   Tr = match2_lim$Tr, 
                   # Include only covariates (and linearized estimated propensity scores)
                   X = match2_lim[, c(6:22)], 
                   Weight.matrix = gm.out2_lim,
                   BiasAdjust = T,
                   ties=T,
                   replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_lim$index.treated, mout2_lim$index.control)
# Create dataset of matches
GM_sup_tt <- match2_lim[sel,]
# Add weights
GM_sup_tt$w <- c(mout2_lim$weights, mout2_lim$weights)

##  GM + WLS with bias adjustment
m_GM_sup_tt <- lm(f_GM_lim, data = GM_sup_tt, weights = w)

### Save models for tables and figure
GM_tt <- list("GM_lower_tt" = m_GM_low_tt, "GM_supreme_tt" = m_GM_sup_tt, 
              "GM_low_tt" = GM_low_tt, "GM_sup_tt" = GM_sup_tt)
save(GM_tt, file = "models/GM-limited-covariates-time-trends.RData")


#### Create tables

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))


# Call time trends models
load("models/OLS-limited-covariates-time-trends.RData")
load("models/EB-limited-covariates-time-trends.RData")
load("models/GM-limited-covariates-time-trends.RData")

names(OLS_tt)
names(EB_tt)
names(GM_tt)

# Lower Court models (limited set of covariates)
m1 <- OLS_tt[["OLS_lower_tt"]] # OLS model
rizzo1_tt <- OLS_tt[["rizzo1_tt"]] # OLS dataset
m2 <- EB_tt[["EB_lower_tt"]] # EB model
EB_low_tt <- EB_tt[["EB_low_tt"]] # EB dataset
m3 <- GM_tt[["GM_lower_tt"]] # GM model
GM_low_tt <- GM_tt[["GM_low_tt"]] # GM dataset

# Supreme Court models (limited set of covariates)
m4 <- OLS_tt[["OLS_supreme_tt"]] # OLS model
rizzo2_tt <- OLS_tt[["rizzo2_tt"]] # OLS dataset
m5 <- EB_tt[["EB_supreme_tt"]] # EB model
EB_sup_tt <- EB_tt[["EB_sup_tt"]] # EB dataset
m6 <- GM_tt[["GM_supreme_tt"]] # GM model
GM_sup_tt <- GM_tt[["GM_sup_tt"]] # GM dataset


## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = ~ city + date, type = "HC1"))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = ~ city + date, type = "HC1"))[,2]
# vcovCL does not compute some SEs (NaN), so I employ feols() from the fixest package
f_GM_lim <- as.formula(paste0("trustbi ~ Tr*party2 + dtime + ", paste0(paste0(names(GM_low_tt)[7:21], collapse = " + "), 
                                                                       " + factor(prov)")))
se3 <- feols(f_GM_lim, cluster = ~city+date, data = GM_low_tt)[["se"]]
se4 <- coeftest(m4, vcovCL(m4, cluster = ~ city + date, type = "HC1"))[,2]
se5 <- coeftest(m5, vcovCL(m5, cluster = ~ city + date, type = "HC1"))[,2]
se6 <- coeftest(m6, vcovCL(m6, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1$resid + m1$fitted.values), 
                 mean(m2$resid + m2$fitted.values),
                 mean(m3$resid + m3$fitted.values),
                 mean(m2$resid + m2$fitted.values),
                 mean(m5$resid + m5$fitted.values),
                 mean(m6$resid + m6$fitted.values)),3)
Y_sd <- round(c(sd(m1$resid + m1$fitted.values), 
                sd(m2$resid + m2$fitted.values),
                sd(m3$resid + m3$fitted.values),
                sd(m2$resid + m2$fitted.values),
                sd(m5$resid + m5$fitted.values),
                sd(m6$resid + m6$fitted.values)),3)

tab_tt <- stargazer(m1, m2, m3, m2, m5, m6,
                    se=list(se1, se2, se3, se4, se5, se6),
                    title="Time Trends", align=TRUE,
                    dep.var.labels.include = FALSE, 
                    dep.var.caption = "",
                    label = "tab:time-trends-add",
                    column.labels = c("\\textbf{Lower Court}",
                                      "\\textbf{Supreme Court}"),
                    column.separate = c(3, 3),
                    keep = c("Tr", "party2", "dtime", "Constant"),
                    covariate.labels = c("Court Ruling","Government Supporter", 
                                         "Days", 
                                         "C. Ruling $\\times$ Gov. Supporter"),
                    star.char = c("+", "*", "**", "***"),
                    star.cutoffs = c(.1, .05, .01, .001),
                    notes.append=FALSE, notes.align = "l", notes.label = "",
                    omit.stat=c("f", "ser", "rsq"),
                    header = FALSE,
                    no.space = TRUE,
                    notes = c("\\small \\parbox[t]{0.9\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. \\textit{Days}: number of days before June 11\\textsuperscript{th} (date of the lower court ruling). Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                    table.placement = "H",
                    add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                     c("sd(Trust)", Y_sd),
                                     c("\\midrule Controls?",
                                       "\\multicolumn{1}{c}{\\checkmark}", 
                                       "\\multicolumn{1}{c}{\\checkmark}",
                                       "\\multicolumn{1}{c}{\\checkmark}",
                                       "\\multicolumn{1}{c}{\\checkmark}",
                                       "\\multicolumn{1}{c}{\\checkmark}", 
                                       "\\multicolumn{1}{c}{\\checkmark}"),
                                     c("Province FE?",
                                       "\\multicolumn{1}{c}{\\checkmark}", 
                                       "\\multicolumn{1}{c}{\\checkmark}",
                                       "\\multicolumn{1}{c}{\\checkmark}",
                                       "\\multicolumn{1}{c}{\\checkmark}",
                                       "\\multicolumn{1}{c}{\\checkmark}", 
                                       "\\multicolumn{1}{c}{\\checkmark}"))
)
# Format table for publication
tab_tt
tab_tt <- gsub("\\\\[-1.8ex]\\hline ", "\\toprule", tab_tt, fixed=TRUE)
tab_tt <- gsub("\\hline \\\\[-1.8ex] ", "", tab_tt, fixed=TRUE)
tab_tt <- gsub("\\hline ", "\\bottomrule", tab_tt, fixed=TRUE)
tab_tt <- gsub("[-1.8ex] ", "", tab_tt, fixed=TRUE)
tab_tt <- gsub("  \\label{tab_tt:time-trends-add} ", 
               "\\tabcolsep=8pt  \\label{tab_tt:time-trends-add}  \\resizebox{\\linewidth}{!}{%", tab_tt, fixed=TRUE)
tab_tt <- gsub("\\end{tabular} ", "\\end{tabular} }", tab_tt, fixed=TRUE)
tab_tt <- gsub("\\begin{tabular}{@{\\extracolsep{5pt}}lD{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} D{.}{.}{-3} } ", 
               "\\begin{tabular}{l*{6}{d{1.3}}}", tab_tt, fixed=TRUE)
tab_tt <- gsub(" & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ ", 
               " & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}", tab_tt, fixed=TRUE)
tab_tt <- gsub("\\\\& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ ", 
               "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\ \\midrule", tab_tt, fixed=TRUE)

sink("tab/time-trends.tex")
cat(tab_tt, sep="\n")
sink()



#################################################
#### Placebo Tests
#### Main text: Figure 5 ####
#################################################

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))


### Other (unrelated) trust items used as placebo:
### # Trust in Armed Forces
### # Trust in Police
### # Trust in the Church
### # Trust in Newspapers
### # Trust in Television
### # Trust in Radio
### # Trust in Relatives
### # Trust in Neighbors
### # Trust in People

# vector of placebo outcomes
outcomes <- c("police", "aforces", "church", 
              "television", "radio", "newspapers", 
              "relatives", "neighbors", "people")
# vector of conditions (lower court and supreme court)
conditions <- c(1,2)

# List to store results in (each element is an outcome)
# interaction coefficients
lplacebo_coef <- list()
# first differences
lplacebo_fdiff <- list()

# Loop over outcomes
for (outcome in outcomes) {
  
  # dataframe for interaction coefficients
  coef <- as.data.frame(matrix(NA, nrow=2, ncol=10))
  colnames(coef) <- c("coef", "se", "p", "lower95", "upper95", 
                      "lower90", "upper90", "Tr","outcome", "n")
  coef["outcome"] <- outcome
  
  # dataframe for first differences
  fdiff <- as.data.frame(matrix(NA, nrow=4, ncol=13))
  colnames(fdiff) <- c("factor", "party2", "AME", "se", "z", "p", "lower95", 
                       "upper95", "lower90", "upper90", "Tr","outcome", "n")
  fdiff["outcome"] <- outcome
  
  # loop over conditions (lower court and supreme court)
  for (Tr in conditions) {
    print(paste0("Outcome: ", outcome))
    print(paste0("Condition: ", Tr))
    # Filter the data and assign it to the variable (using limited set of covariates)
    sel_lim <-	rizzo$Tr %in% c(0,Tr) &
      !is.na(rizzo$party2) &
      !is.na(rizzo$age) &
      !is.na(rizzo$female) &
      !is.na(rizzo$education) &
      !is.na(rizzo$SES_ord) &
      !is.na(rizzo$subinc_ord) &
      !is.na(rizzo$class_ord) &
      !is.na(rizzo$religion) &
      !is.na(rizzo$city) &
      !is.na(rizzo[[outcome]])
    
    data_lim <- rizzo[sel_lim,]
    # Convert supreme court indicator into 0-1 (rather than 0-2)
    if (Tr == 2) {
      data_lim$Tr <- ifelse(data_lim$Tr==2, 1, 0)
    }
    
    # get model matrix
    data <- data.frame(model.matrix(
      lm(data_lim[[outcome]] ~ 	Tr*party2 + age + female + education + 
           SES_ord + subinc_ord + class_ord + religion + factor(prov),
         data = data_lim)
    ))
    
    # remove intercept and interaction term
    data <- data[, setdiff(names(data), c("X.Intercept.", "Tr.party2"))]
    
    # remove columns that start with "factor.prov."
    data <- data[, !grepl("^factor\\.prov\\.", names(data))]
    
    # bind dataset with outcome, city, prov, and date columns
    data <- cbind(data_lim[[outcome]], 
                  data_lim$city, data_lim$prov, data_lim$date, 
                  data)
    
    # rename columns
    colnames(data)[1] <- "outcome"
    colnames(data)[2] <- "city"
    colnames(data)[3] <- "prov"
    colnames(data)[4] <- "date"
    
    # order data (to add weights correctly later)
    data <- rbind(data[data$Tr == 0,], 
                  data[data$Tr == 1,])
    
    # compute weights (exclude outcome, treatment, prov, city, date from covariates)
    out <- ebalance(Treatment = data$Tr, X = data[, c(6:21)])
    
    # add weights to dataset
    data$w <- c(out$w, rep(1, nrow(data[data$Tr == 1,])))
    names(data)
    
    # fit model
    mod <- lm(outcome ~ Tr*party2 + . -(city + date + w),
              weights = w, data = data)
    
    # compute cluster-robust vcov matrix
    vcov <- vcovCL(mod, cluster = ~city + date)
    
    # compute coef, SE, p, and 90-95 CIs (interaction coefficients)
    coef_coef <- mod$coefficients["Tr:party2"]
    se_coef <- coeftest(mod, vcov = vcov)["Tr:party2",2]
    p_coef <- coeftest(mod, vcov = vcov)["Tr:party2",4]
    CI95_coef <- confint(mod,vcov = vcov, level = 0.95)["Tr:party2",]
    CI90_coef <- confint(mod,vcov = vcov, level = 0.90)["Tr:party2",]
    
    # compute AME, SE, p, and 90-95 CIs (first differences)
    CI95_fdiff <- summary(margins(mod, variables = "Tr", at = list(party2 = 0:1),
                                  vcov = vcov))
    CI90party0_fdiff <- confint(margins(mod, variables = "Tr", at = list(party2 = 0),
                                        vcov = vcov), level = 0.90)
    CI90party1_fdiff <- confint(margins(mod, variables = "Tr", at = list(party2 = 1),
                                        vcov = vcov), level = 0.90)
    
    # Update the dataframe with the results
    if(Tr == 1){
      # interaction coefficients
      coef[1, 1] <- coef_coef
      coef[1, 2] <- se_coef
      coef[1, 3] <- p_coef
      coef[1, 4:5] <- CI95_coef
      coef[1, 6:7] <- CI90_coef
      coef[1, "Tr"] <- "lower"
      coef[1, "n"] <- nrow(data)
      
      # first differences
      fdiff[1:2, 1:8] <- CI95_fdiff
      fdiff[1, 9:10] <- CI90party0_fdiff
      fdiff[2, 9:10] <- CI90party1_fdiff
      fdiff[1:2, "Tr"] <- "lower"
      fdiff[1, "n"] <- sum(data$party2 == 0, na.rm = TRUE)
      fdiff[2, "n"] <- sum(data$party2 == 1, na.rm = TRUE)
    }else{
      # interaction coefficients
      coef[2, 1] <- coef_coef
      coef[2, 2] <- se_coef
      coef[2, 3] <- p_coef
      coef[2, 4:5] <- CI95_coef
      coef[2, 6:7] <- CI90_coef
      coef[2, "Tr"] <- "supreme"
      coef[2, "n"] <- nrow(data)
      
      # first differences
      fdiff[3:4, 1:8] <- CI95_fdiff
      fdiff[3, 9:10] <- CI90party0_fdiff
      fdiff[4, 9:10] <- CI90party1_fdiff
      fdiff[3:4, "Tr"] <- "supreme"
      fdiff[3, "n"] <- sum(data$party2 == 0, na.rm = TRUE)
      fdiff[4, "n"] <- sum(data$party2 == 1, na.rm = TRUE)
    }
    print(paste0("Complete: ", outcome))
  }
  
  index <- match(outcome, outcomes)  # Get the index of the variable
  lplacebo_coef[[outcome]] <- coef
  lplacebo_fdiff[[outcome]] <- fdiff
}

## Check
head(coef)
head(fdiff)

lplacebo_coef[[9]]
lplacebo_fdiff[[9]]

placebo <- list("coefficients" = lplacebo_coef, 
                "first differences" = lplacebo_fdiff)

# Stack outcome data into single dataframes
coef <- do.call("rbind", placebo[["coefficients"]])
fdiff <- do.call("rbind", placebo[["first differences"]])
rm(placebo)

head(fdiff)
head(fdiff[,c(1:3,11:12)],10)

# Reorder first differences to ease visual comparison in plot
# Estimates for opposition supporters (party == 0) to the left of each trust item 
# Estimates for government supporters (party == 1) to the right of each trust item
fdiff <- fdiff[order(fdiff$outcome, fdiff$party2), ]
head(fdiff[,c(1:3,11:12)],10)

# Order coef as in fdiff
coef <- coef[order(coef$outcome), ]

# Check
cbind(unique(coef$outcome), unique(fdiff$outcome))


## Set common features for both panels of Figure 5

# Vector of y labels
unique(coef$outcome)
ylab <- c("Armed\nForces", "Church", "Neighbors", "Newspapers", "People", "Police", 
          "Radio", "Relatives", "TV")

# x-position of point estimates and CIs (leaving space between outcomes)
n_coef <- 26
n_fdiff <- 44
xticks_fdiff <- seq(1, n_fdiff, by = 1)[seq(1, n_fdiff, by = 1) %% 5 != 0]
xticks_coef <- seq(1, 44, by = 0.5)[seq(1, 44, by = 0.5)%% 5 == 2.5 | 
                                      seq(1, 44, by = 0.5) %% 5 == 3.5]

# These options are common for all plots, 
# so set them up just once (as function or expression)
plots <- function(main, ylim, xlim) {
  plot(1, 1, xaxt = "n", yaxt = "n", 
       type = "n", ylab = "", xlab = "",
       xlim = xlim, 
       main = main, 
       ylim = ylim)
}

xaxis <- function(at) {
  axis(side = 1, at=at, las=1, tcl=-0.30,labels = FALSE)
}

xtext <- function(x, y) {
  text(x = x, y, 
       labels = ylab,
       adj = c(0.5,1), xpd = NA, srt = 0, cex = 0.9)
}

yaxis <- function(at){
  axis(2,cex.axis=0.9, las = 0, tcl=-0.4, labels = FALSE,
       at = at)
}

ytext <- expression(
  text(x = -1, y = seq(-0.4, 0.4, 0.2), cex = 1, 
       labels = seq(-0.4, 0.4, 0.2), 
       srt = 90, 
       adj = 0.5, xpd = NA)
)


# Set plot file
#png(file = "fig/png-figures/placebo-plots.png", width = 8, height = 8, units = "in", res = 600)
#tiff(file = "fig/tiff-figures/placebo-plots.tif", width = 8, height = 8, units = "in", res = 600)
pdf(file = "fig/placebo-plots.pdf",  
    width = 8, # The width of the plot in inches
    height = 8) # The height of the plot in inches
par(mar=c(1.5, 2, 2, 0.5), oma=c(1, 1, 0, 0)) # Set up margins by number of lines
layout(matrix(1:2, ncol=1), # panel figure?
       widths=c(1, 1))

### Interaction coefficients ###
plots(ylim = c(min(coef$lower95), max(coef$upper95) + 0.05),
      xlim = c(2, n_fdiff-1), 
      main = "Interaction Coefficients")

xaxis(at = seq(2.5,n_fdiff, by=5))

xtext(x = seq(2.5,n_fdiff, by=5),
      y = min(coef$lower95)-0.075)

yaxis(at = seq(-0.4, 0.4, 0.2))

eval(ytext)

mtext("Interaction Coefficient", side = 2, line = 2)

segments(x0=xticks_coef, y0=coef$lower95,
         x1=xticks_coef, y1=coef$upper95, 
         lty = 1, lwd = 2.5, col = c("darkgray", "black"))
segments(x0=xticks_coef, y0=coef$lower90, 
         x1=xticks_coef, y1=coef$upper90, 
         lty = 1, lwd = 3.5, col = c("darkgray", "black"))

points(xticks_coef, coef$coef,
       cex = 1.1, pch = c(21), col = c("darkgray", "black"), 
       bg = c("white", "white"))

abline(v = seq(5,64,5), col = "lightgray", lty=1)

abline(h = 0, col = "red", lty=2, lwd = 1.5)

legend("top", legend=c("Lower Court", "Supreme Court"),
       lty = 1, lwd = 2, col = c("darkgray","black"),
       pch = c(21,21), pt.bg = c("white","white"),
       ncol = 1, cex = 0.8, bg = "white")

### First differences ###
plots(ylim = c(min(fdiff$lower95), max(fdiff$upper95) + 0.05), 
      xlim = c(2, n_fdiff-1),
      main = "First Differences")

xaxis(at = seq(2.5,n_fdiff, by=5))

xtext(x = seq(2.5,n_fdiff, by=5),
      y = min(fdiff$lower95)-0.075)

yaxis(at = seq(-0.4, 0.4, 0.2))

eval(ytext)

mtext("Effect on Outcome", side = 2, line = 2)

segments(x0=xticks_fdiff, y0=fdiff$lower95,
         x1=xticks_fdiff, y1=fdiff$upper95, 
         lty = 1, lwd = 2, col = c("darkgray", "black", "darkgray","black"))
segments(x0=xticks_fdiff, y0=fdiff$lower90, 
         x1=xticks_fdiff, y1=fdiff$upper90, 
         lty = 1, lwd = 3, col = c("darkgray", "black", "darkgray","black"))

points(xticks_fdiff, fdiff$AME,
       cex = 1, pch = c(21,21,24,24), col = c("darkgray", "black", "darkgray","black"), 
       bg = c("darkgray", "black", "darkgray","black"))

abline(v = seq(5,64,5), col = "lightgray", lty=1)

abline(h = 0, col = "red", lty=2, lwd = 1.5)

legend("topright", legend=c("Opp. Supp., Lower C.", "Opp. Supp., Supreme C.", 
                            "Gov. Supp., Lower C.", "Gov. Supp., Supreme C."),
       lty = 1, lwd = 2, col = c("darkgray","black", "darkgray", "black"),
       pch = c(21,21,24,24), pt.bg = c("darkgray","black", "darkgray", "black"),
       ncol = 2, cex = 0.8, bg = "white")

dev.off()



#################################################
#### Sensitivity Analysis
#### Appendix: Tables G3.1 and G3.2 ####
#################################################

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call models
load("models/OLS-limited-covariates.RData")
load("models/EB-limited-covariates.RData")
load("models/GM-limited-covariates.RData")

names(OLS_lim)
names(EB_lim)
names(GM_lim)

# Lower Court models (limited set of covariates)
m1 <- OLS_lim[["OLS_lim_lower"]] # OLS model
m2 <- EB_lim[["EB_lim_lower"]] # EB model
EB_lim_low <- EB_lim[["EB_lim_low"]] # EB dataset
m3 <- GM_lim[["GM_lim_lower"]] # GM model
GM_lim_low <- GM_lim[["GM_lim_low"]] # GM dataset
# Supreme Court models (limited set of covariates)
m4 <- OLS_lim[["OLS_lim_supreme"]] # OLS model
m5 <- EB_lim[["EB_lim_supreme"]] # EB model
EB_lim_sup <- EB_lim[["EB_lim_sup"]] # EB dataset
m6 <- GM_lim[["GM_lim_supreme"]] # GM model
GM_lim_sup <- GM_lim[["GM_lim_sup"]] # GM dataset

## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = ~ city + date, type = "HC1"))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = ~ city + date, type = "HC1"))[,2]
se3 <- coeftest(m3, vcovCL(m3, cluster = ~ city + date, type = "HC1"))[,2]
se4 <- coeftest(m4, vcovCL(m4, cluster = ~ city + date, type = "HC1"))[,2]
se5 <- coeftest(m5, vcovCL(m5, cluster = ~ city + date, type = "HC1"))[,2]
se6 <- coeftest(m6, vcovCL(m6, cluster = ~ city + date, type = "HC1"))[,2]


###########################################
# Appendix: Table G3.2 (Sensitivity Analysis using konfound() (Narvaiz et al. 2024))

models <- list("UBlow" = m1, 
               "EBlow" = m2, 
               "Mlow" = m3, 
               "UBsup" = m4,
               "EBsup" = m5, 
               "Msup" = m6)

SEs <- list("se1" = se1, 
            "se2" = se2, 
            "se3" = se3, 
            "se4" = se4,
            "se5" = se5, 
            "se6" = se6)

konfound_results <- as.data.frame(matrix(NA, nrow = 6, ncol = 6))
rownames(konfound_results) <- c("OLS", "EB+WLS", "GM+WLS", 
                                "OLS2", "EB+WLS2", "GM+WLS2")

# Get konfound() statistics
for (i in 1:6){
  model <- names(models)[i]
  # interaction coefficient
  coef <- models[[model]]$coefficients["Tr:party2"]
  # Robust SEs clustered by city and date
  se <- SEs[[i]]["Tr:party2"]
  # Number of covariates (in OLS is a factor; in EB and GM models factors are dummied out)
  if(i %in% c(1,4)){
    n_covars <- 7
  } else{
    n_covars <- 15
  }
  
  results <- pkonfound(est_eff = coef,
                       std_err = se, 
                       alpha = 0.05,
                       n_obs = nrow(models[[model]]$model), 
                       n_covariates = n_covars, 
                       index = "IT",
                       to_return = "raw_output")
  konfound_results[i,1] <- coef
  konfound_results[i,2] <- results$beta_threshold
  konfound_results[i,3] <- results$perc_bias_to_change
  konfound_results[i,4] <- results$RIR_primary
  konfound_results[i,5] <- results$rxcvGz
  konfound_results[i,6] <- results$itcvGz
}

tab_konfound <- as.data.frame(konfound_results)
tab_konfound$Model <- rownames(tab_konfound)


# save table
sink("tab/konfound-results.tex")

# Table header
cat("\\begin{table}[H]\n")
cat("\\centering\n")
cat("\\caption{Sensitivity Analysis (Narvaiz et al. 2024)}\n")
cat("\\tabcolsep=4pt\n")
cat("\\label{tab:sensitivity-konfound}\n")
cat("\\resizebox{\\linewidth}{!}{\n")
cat("\\begin{tabular}{l*{6}{d{1.3}}}\n")
cat("\\toprule\n")
cat("\\multicolumn{1}{l}{Model} & 
     \\multicolumn{1}{c}{$\\hat{\\beta}$} & 
     \\multicolumn{1}{c}{\\makecell[c]{$\\hat{\\beta}$\\\\threshold}} & 
     \\multicolumn{1}{c}{\\small \\makecell[c]{\\% estimate bias to\\\\change inference}} & 
     \\multicolumn{1}{c}{\\small \\makecell[c]{\\# of null cases to\\\\invalidate inference}} & 
     \\multicolumn{1}{c}{\\small \\makecell[c]{Omitted variable\\\\correlation}} & 
     \\multicolumn{1}{c}{\\makecell[c]{ITCV\\\\(Frank 2000)}} \\\\\n")
cat("\\midrule\n")

cat("\\textit{Lower Court} & & & & & & \\\\\n")
for (i in 1:3) {
  row <- tab_konfound[i, ]
  cat(sprintf("%s & %.3f & %.3f & %.2f & %d & %.3f & %.3f \\\\\n",
              row[["Model"]], row[["V1"]], row[["V2"]],
              row[["V3"]], row[["V4"]], row[["V5"]], row[["V6"]]))
}

cat("\\midrule\n")

# Supreme court models
cat("\\textit{Supreme Court} & & & & & & \\\\\n")
for (i in 4:6) {
  row <- tab_konfound[i, ]
  cat(sprintf("%s & %.3f & %.3f & %.2f & %d & %.3f & %.3f \\\\\n",
              row[["Model"]], row[["V1"]], row[["V2"]],
              row[["V3"]], row[["V4"]], row[["V5"]], row[["V6"]]))
}

# End of table
cat("\\bottomrule\n")
cat("\\end{tabular}\n")
cat("}\n")
cat("\\end{table}\n")

sink()


###########################################
# Appendix: Table G3.1 (Sensitivity Analysis using sensemakr (Cinelli and Hazlett 2020))

coef <- c(coeftest(m1, vcovCL(m1, cluster = ~city + date))["Tr:party2",1], 
          coeftest(m2, vcovCL(m2, cluster = ~city + date))["Tr:party2",1],
          coeftest(m3, vcovCL(m3, cluster = ~city + date))["Tr:party2",1],
          coeftest(m4, vcovCL(m4, cluster = ~city + date))["Tr:party2",1],
          coeftest(m5, vcovCL(m5, cluster = ~city + date))["Tr:party2",1],
          coeftest(m6, vcovCL(m6, cluster = ~city + date))["Tr:party2",1])

se <- c(coeftest(m1, vcovCL(m1, cluster = ~city + date))["Tr:party2",2], 
        coeftest(m2, vcovCL(m2, cluster = ~city + date))["Tr:party2",2],
        coeftest(m3, vcovCL(m3, cluster = ~city + date))["Tr:party2",2],
        coeftest(m4, vcovCL(m4, cluster = ~city + date))["Tr:party2",2],
        coeftest(m5, vcovCL(m5, cluster = ~city + date))["Tr:party2",2],
        coeftest(m6, vcovCL(m6, cluster = ~city + date))["Tr:party2",2])

# t-statistic of gov.supporter in outcome regression
t.yX <- c(coeftest(m1, vcovCL(m1, cluster = ~city + date))["party2",3], 
          coeftest(m3, vcovCL(m3, cluster = ~city + date))["party2",3],
          coeftest(m3, vcovCL(m3, cluster = ~city + date))["party2",3],
          coeftest(m4, vcovCL(m4, cluster = ~city + date))["party2",3],
          coeftest(m5, vcovCL(m5, cluster = ~city + date))["party2",3],
          coeftest(m6, vcovCL(m6, cluster = ~city + date))["party2",3])

dof <- c(summary(m1)$df[2], 
         summary(m2)$df[2], 
         summary(m3)$df[2], 
         summary(m4)$df[2], 
         summary(m5)$df[2], 
         summary(m6)$df[2])


# Treatment regressions
OLS.low <- lm(Tr ~ party2 + age + female + education + SES_ord + 
                subinc_ord + class_ord + religion + factor(prov), 
              data = rizzo1_lim)
eb.low <- lm(Tr ~ party2 + age + female + education + 
               SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
               subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save +
               class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
               religionCatolica + religionEvangelica + religionOtra + 
               factor(prov), data = EB_lim_low)
gm.low <- lm(Tr ~ party2 + age + female + education + 
               SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
               subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save +
               class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
               religionCatolica + religionEvangelica + religionOtra + 
               factor(prov), data = GM_lim_low)
OLS.sup <- lm(Tr ~ party2 + age + female + education + SES_ord + 
                subinc_ord + class_ord + religion + factor(prov), 
              data = rizzo2_lim)
eb.sup <- lm(Tr ~ party2 + age + female + education + 
               SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
               subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save +
               class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
               religionCatolica + religionEvangelica + religionOtra + 
               factor(prov), data = EB_lim_sup)
gm.sup <- lm(Tr ~ party2 + age + female + education + 
               SES_ordNot.bad + SES_ordGood + SES_ordVery.good +
               subinc_ordNot.suff + subinc_ordJust.suff + subinc_ordSuff.save +
               class_ordMiddle.lower + class_ordMiddle + class_ordMiddle.Upper +
               religionCatolica + religionEvangelica + religionOtra + 
               factor(prov), data = GM_lim_sup)

# t-statistic of gov.supporter in treatment regression
t.dX <- c(coeftest(OLS.low, vcovCL(OLS.low, cluster = ~city + date))["party2",3], 
          coeftest(OLS.sup, vcovCL(OLS.sup, cluster = ~city + date))["party2",3],
          coeftest(eb.low, vcovCL(eb.low, cluster = ~city + date))["party2",3],
          coeftest(eb.sup, vcovCL(eb.sup, cluster = ~city + date))["party2",3],
          coeftest(gm.low, vcovCL(gm.low, cluster = ~city + date))["party2",3],
          coeftest(gm.sup, vcovCL(gm.sup, cluster = ~city + date))["party2",3])

dof.dx <- c(summary(OLS.low)$df[2], 
            summary(OLS.sup)$df[2], 
            summary(eb.low)$df[2], 
            summary(eb.sup)$df[2], 
            summary(gm.low)$df[2], 
            summary(gm.sup)$df[2])

sensitivity <- as.data.frame(matrix(NA, nrow = 6, ncol = 8))
rownames(sensitivity) <- c("OLS", "EB+WLS", "GM+WLS", 
                           "OLS2", "EB+WLS2", "GM+WLS2")

for (i in 1:length(coef)){
  sense <- sensemakr(
    estimate = coef[i],
    se = se[i],
    dof = dof[i],
    treatment = "Tr:party2",
    benchmark_covariates = "party2",
    kd = 1,
    ky = 1, 
    q = 1,
    alpha = 0.5, 
    reduce = TRUE)
  
  # Use the t statistic of gov.supporter in the outcome regression
  # to compute the partial R2 of gov.supporter with the outcome.
  r2yxj.dx <- partial_r2(t_statistic = t.yX[i], dof = dof[i])
  
  # Use the t-value of gov.supporter in the *treatment* regression
  # to compute the partial R2 of gov.supporter with the treatment
  r2dxj.x <- partial_r2(t_statistic = t.dX[i], dof = dof.dx[i])
  
  bounds <- ovb_partial_r2_bound(r2dxj.x = r2dxj.x,
                                 r2yxj.dx = r2yxj.dx,
                                 kd = 2,
                                 ky = 1)
  
  sensitivity[i, 1:6] <- sense$sensitivity_stats[1, 2:7]
  sensitivity[i, 7] <- bounds$r2yz.dx
  sensitivity[i, 8] <- bounds$r2dz.x
  
}
sensitivity


tab_sensitivity <- as.data.frame(sensitivity)
tab_sensitivity$Model <- rownames(tab_sensitivity)


# save table
sink("tab/sensemakr-results.tex")

# Table header
cat("\\begin{table}[H]\n")
cat("\\centering\n")
cat("\\caption{Sensitivity Analysis (Cinelli and Hazlett 2020)}\n")
cat("\\tabcolsep=4pt\n")
cat("\\label{tab:sensitivity-sensemakr}\n")
cat("\\resizebox{\\linewidth}{!}{\n")
cat("\\begin{tabular}{l*{8}{d{1.3}}}\n")
cat("\\toprule\n")
cat("& & & & & & & \\multicolumn{2}{c}{\\small Bound ($1 \\times$Gov. Supporter)}\\\\\n")

cat("\\cmidrule{8-9}\n")
cat("\\multicolumn{1}{l}{Model} &
					\\multicolumn{1}{c}{Estimate} & 
					\\multicolumn{1}{c}{s.e.} & 
					\\multicolumn{1}{c}{$t$-value} & 
					\\multicolumn{1}{c}{$R^2_{Y \\sim D | {\\bf X}}$} & 
					\\multicolumn{1}{c}{$RV_{q = 1}$} & 
					\\multicolumn{1}{c}{$RV_{q = 1, \\alpha = 0.5}$} &
					\\multicolumn{1}{c}{$R^2_{Y \\sim Z | {\\bf X},D}$} &
					\\multicolumn{1}{c}{$R^2_{D \\sim Z | {\\bf X}}$}
					\\\\\n")
cat("\\midrule\n")
cat("\n")
cat("\n")
cat("\n")
cat("\n")
cat("\n")

cat("\\textit{Lower Court} & & & & & & & & \\\\\n")
for (i in 1:3) {
  row <- tab_sensitivity[i, ]
  # Format the last column if very small
  val <- row[["V8"]]
  last_col <- ifelse(val < 0.001, "<0.001", sprintf("%.3f", val))
  
  cat(sprintf("%s & %.3f & %.3f & %.3f & %.3f & %.3f & %.3f & %.3f & %s \\\\\n",
              row[["Model"]], row[["V1"]], row[["V2"]],
              row[["V3"]], row[["V4"]], row[["V5"]], row[["V6"]], 
              row[["V7"]], last_col))
}

cat("\\midrule\n")

# Supreme court models
cat("\\textit{Supreme Court} & & & & & & & & \\\\\n")
for (i in 4:6) {
  row <- tab_sensitivity[i, ]
  # Format the last column if very small
  val <- row[["V8"]]
  last_col <- ifelse(val < 0.001, "<0.001", sprintf("%.3f", val))
  cat(sprintf("%s & %.3f & %.3f & %.3f & %.3f & %.3f & %.3f & %.3f & %s \\\\\n",
              row[["Model"]], row[["V1"]], row[["V2"]],
              row[["V3"]], row[["V4"]], row[["V5"]], row[["V6"]], 
              row[["V7"]], last_col))
}

# End of table
cat("\\bottomrule\n")
cat("\\end{tabular}\n")
cat("}\n")
cat("\\end{table}\n")

sink()


#################################################
#### Analyses including nonpartisan respondents
#### Appendix: Figure H1.1 and Table H1.1 ####
#################################################

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Create party3 indicator (0=outpartisans, 1=copartisans, 3=nonpartisans)
table(rizzo$party2, useNA = "always")

rizzo$party3 <- ifelse(is.na(rizzo$party2), "non", 
                       ifelse(rizzo$party2 == 0, "out",
                              ifelse(rizzo$party2== 1, "co", NA)))

table(rizzo$party3, useNA = "always")

table(rizzo$party2, rizzo$party3, useNA = "always")

rizzo$party3 <- factor(rizzo$party3, levels = c("out", "co", "non"))

table(rizzo$party3, useNA = "always")

# Limited set of covariates
sel_nonpartisans <-	!is.na(rizzo$Tr) &
  !is.na(rizzo$party3) &
  !is.na(rizzo$age) &
  !is.na(rizzo$trustbi) &
  !is.na(rizzo$female) &
  !is.na(rizzo$education) &
  !is.na(rizzo$SES_ord) &
  !is.na(rizzo$subinc_ord) &
  !is.na(rizzo$class_ord) &
  !is.na(rizzo$religion) &
  !is.na(rizzo$city)

table(sel_nonpartisans)
rizzo_nonpartisansited <- rizzo[sel_nonpartisans,]
dim(rizzo_nonpartisansited)

## Limited data set
table(rizzo_nonpartisansited$date, rizzo_nonpartisansited$Tr)
rizzo1_nonpartisans <- rizzo_nonpartisansited[rizzo_nonpartisansited$Tr != 2, ]
rizzo2_nonpartisans <- rizzo_nonpartisansited[rizzo_nonpartisansited$Tr != 1, ]
rizzo2_nonpartisans$Tr <- ifelse(rizzo2_nonpartisans$Tr == 2, 1, 0)


# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext",
          "rizzo1_nonpartisans", "rizzo2_nonpartisans")
rm(list = setdiff(ls(), keep))


## OLS models
f_OLS_nonpartisans <- as.formula("trustbi ~ Tr*party3 + age + female + education + 
                        SES_ord + subinc_ord + class_ord + religion + factor(prov)")

## Lower court
m_OLS_nonpartisans_low <- lm(f_OLS_nonpartisans, data = rizzo1_nonpartisans)

## Supreme court
m_OLS_nonpartisans_sup <- lm(f_OLS_nonpartisans, data = rizzo2_nonpartisans)

### Save models for tables and figure
OLS_nonpartisans <- list("OLS_nonpartisans_lower" = m_OLS_nonpartisans_low, "OLS_nonpartisans_supreme" = m_OLS_nonpartisans_sup, 
                         "rizzo1_nonpartisans" = rizzo1_nonpartisans, "rizzo2_nonpartisans" = rizzo2_nonpartisans)
save(OLS_nonpartisans, file = "models/OLS-nonpartisans-covariates.RData")


###########
### Entropy balance + WLS models (binary outcome)
###########

## Lower Court
# Prepare covariate matrix for ebal() function
# ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party3 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
# Get covariate matrix
EB_nonpartisans_low <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo1_nonpartisans))
)

colnames(EB_nonpartisans_low)

# Remove intercept
EB_nonpartisans_low <- EB_nonpartisans_low[, -1]

colnames(EB_nonpartisans_low)

# Add in outcomes and missing variables
EB_nonpartisans_low <- cbind("trustbi" = rizzo1_nonpartisans$trustbi, 
                             "city" = rizzo1_nonpartisans$city, # City (clustered SEs and city FE)
                             "date" = rizzo1_nonpartisans$date, # Date of interview (clustered SEs)
                             "prov" = rizzo1_nonpartisans$prov, # Province (province FE)
                             EB_nonpartisans_low, # Covariate matrix
                             "party3" = rizzo1_nonpartisans$party3)
names(EB_nonpartisans_low)

# Order observations to add entropy balance weights (controls first)
EB_nonpartisans_low <- rbind(EB_nonpartisans_low[EB_nonpartisans_low$Tr == 0,], 
                             EB_nonpartisans_low[EB_nonpartisans_low$Tr == 1,])

colnames(EB_nonpartisans_low)

# Compute entropy balance (EB) weights
out1_nonpartisans <- ebalance(Treatment = EB_nonpartisans_low$Tr, 
                              X = EB_nonpartisans_low[,6:22]) # include only covariates to balance on

# Add weights to (ordered) dataset
EB_nonpartisans_low$w <- c(out1_nonpartisans$w, # weights for control observations 
                           rep(1, nrow(EB_nonpartisans_low[EB_nonpartisans_low$Tr == 1,])))

# Check distribution of weights
hist(out1_nonpartisans$w, 100) # weights are well behaved

names(EB_nonpartisans_low)

# Formula for regressions with nonpartisans covariate dataset
names(EB_nonpartisans_low)
f_EB_nonpartisans <- as.formula(paste0("trustbi ~ Tr*party3 + ", 
                                       paste0(paste0(names(EB_nonpartisans_low)[8:22], collapse = " + "), 
                                              " + factor(prov)")))

# WLS with bias adjustment
m_EB_nonpartisans_low <- lm(f_EB_nonpartisans, data = EB_nonpartisans_low, weights = w)


## Supreme Court
# Prepare covariate matrix for ebal() function
# ebal() doesn't accept factor variables -- factors need to be converted to dummies
covars <- "party3 + age + female + education + SES_ord + subinc_ord + class_ord + religion"
# Get covariate matrix
EB_nonpartisans_sup <- data.frame(model.matrix(
  lm(as.formula(paste0("trustbi ~ Tr + ", covars)), data = rizzo2_nonpartisans))
)

colnames(EB_nonpartisans_sup)

# Remove intercept
EB_nonpartisans_sup <- EB_nonpartisans_sup[, -1]

colnames(EB_nonpartisans_sup)

# Add in outcomes and missing variables
EB_nonpartisans_sup <- cbind("trustbi" = rizzo2_nonpartisans$trustbi, 
                             "city" = rizzo2_nonpartisans$city, # City (clustered SEs and city FE)
                             "date" = rizzo2_nonpartisans$date, # Date of interview (clustered SEs)
                             "prov" = rizzo2_nonpartisans$prov, # Province (province FE)
                             EB_nonpartisans_sup, # Covariate matrix
                             "party3" = rizzo2_nonpartisans$party3)
names(EB_nonpartisans_sup)

# Order observations to add entropy balance weights (controls first)
EB_nonpartisans_sup <- rbind(EB_nonpartisans_sup[EB_nonpartisans_sup$Tr == 0,], 
                             EB_nonpartisans_sup[EB_nonpartisans_sup$Tr == 1,])

colnames(EB_nonpartisans_sup)

# Compute entropy balance (EB) weights
out2_nonpartisans <- ebalance(Treatment = EB_nonpartisans_sup$Tr, 
                              X = EB_nonpartisans_sup[,6:22]) # include only covariates to balance on

# Check distribution of weights
hist(out2_nonpartisans$w, 100) # weights are well behaved

# Add weights to (ordered) dataset
EB_nonpartisans_sup$w <- c(out2_nonpartisans$w, # weights for control observations 
                           rep(1, nrow(EB_nonpartisans_sup[EB_nonpartisans_sup$Tr == 1,])))

# WLS with bias adjustment
m_EB_nonpartisans_sup <- lm(f_EB_nonpartisans, data = EB_nonpartisans_sup, weights = w)


### Save models for tables and figure
EB_nonpartisans <- list("EB_nonpartisans_lower" = m_EB_nonpartisans_low, "EB_nonpartisans_supreme" = m_EB_nonpartisans_sup, 
                        "EB_nonpartisans_low" = EB_nonpartisans_low, "EB_nonpartisans_sup" = EB_nonpartisans_sup)
save(EB_nonpartisans, file = "models/EB-nonpartisans-covariates.RData")


###########
### Genetic matching + WLS models (binary outcome)
###########

## Lower Court

# Prepare covariate matrix for genMatch() function
# Compute linearized estimated propensity scores
ps.out1_nonpartisans <- glm(Tr ~ party3 + age + female + education + SES_ord + 
                              subinc_ord + class_ord + religion + factor(prov), 
                            family = binomial(link = "probit"), data = rizzo1_nonpartisans)
e <- fitted(ps.out1_nonpartisans, type = "response")
l <- log(e/(1-e))

# Get covariate matrix
match1_nonpartisans <- data.frame(model.matrix(ps.out1_nonpartisans))
names(match1_nonpartisans)
# Remove intercept and prov
match1_nonpartisans <- match1_nonpartisans[,-c(1,19:29)]
names(match1_nonpartisans)
# Add linearized estimated propensity scores
match1_nonpartisans$l <- l
names(match1_nonpartisans)
# Add in other variables
match1_nonpartisans <- cbind("trustbi" = rizzo1_nonpartisans$trustbi, 
                             "Tr" = rizzo1_nonpartisans$Tr, 
                             "city" = rizzo1_nonpartisans$city, # City (clustered SEs and city FE)
                             "date" = rizzo1_nonpartisans$date, # Date of interview (clustered SEs)
                             "prov" = rizzo1_nonpartisans$prov, # Province (province FE)
                             match1_nonpartisans, 
                             "party3" = rizzo1_nonpartisans$party3)
names(match1_nonpartisans)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores) 

# Computation takes about 90 minutes
# Solution Found Generation 63
# Number of Generations Run 114
set.seed(1)
gm.out1_nonpartisans <-	GenMatch(Tr = match1_nonpartisans$Tr, 
                                 # Include only covariates (and linearized estimated propensity scores)
                                 X = match1_nonpartisans[, c(6:23)], 
                                 pop.size = 5000,
                                 wait.generations = 50, 
                                 cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out1_nonpartisans, file = "genetic-matching-output/gen-match-output-lower-nonpartisans.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-lower-nonpartisans.RData")

names(match1_nonpartisans)

# Use Match() to obtain dataset of matched observations
mout1_nonpartisans <- Match(Tr = match1_nonpartisans$Tr, 
                            # Include only covariates (and linearized estimated propensity scores)
                            X = match1_nonpartisans[, c(6:23)], 
                            Weight.matrix = gm.out1_nonpartisans,
                            ties=T, 
                            replace=T)

# Vectors of matched control and treated observations
sel <- c(mout1_nonpartisans$index.treated, mout1_nonpartisans$index.control)
# Create dataset of matches
GM_nonpartisans_low <- match1_nonpartisans[sel,]
# Add weights
GM_nonpartisans_low$w <- c(mout1_nonpartisans$weights, mout1_nonpartisans$weights)

##  GM + WLS with bias adjustment
names(GM_nonpartisans_low)

# Formula for regressions with nonpartisans covariate dataset
f_GM_nonpartisans <- as.formula(paste0("trustbi ~ Tr*party3 + ", 
                                       paste0(paste0(names(GM_nonpartisans_low)[8:22], collapse = " + "), 
                                              " + factor(prov)")))

m_GM_nonpartisans_low <- lm(f_GM_nonpartisans, data = GM_nonpartisans_low, weights = w)


## Supreme Court

# Prepare covariate matrix for genMatch() function
# Compute linearized estimated propensity scores
ps.out2_nonpartisans <- glm(Tr ~ party3 + age + female + education + SES_ord + 
                              subinc_ord + class_ord + religion + factor(prov), 
                            family = binomial(link = "probit"), data = rizzo2_nonpartisans)
e <- fitted(ps.out2_nonpartisans, type = "response")
l <- log(e/(1-e))

# Get covariate matrix
match2_nonpartisans <- data.frame(model.matrix(ps.out2_nonpartisans))
names(match2_nonpartisans)
# Remove intercept and prov
match2_nonpartisans <- match2_nonpartisans[,-c(1, 19:31)]


names(match2_nonpartisans)

# Add linearized estimated propensity scores
match2_nonpartisans$l <- l
names(match2_nonpartisans)
# Add in other variables
match2_nonpartisans <- cbind("trustbi" = rizzo2_nonpartisans$trustbi, 
                             "Tr" = rizzo2_nonpartisans$Tr, 
                             "city" = rizzo2_nonpartisans$city, # City (clustered SEs and city FE)
                             "date" = rizzo2_nonpartisans$date, # Date of interview (clustered SEs)
                             "prov" = rizzo2_nonpartisans$prov, # Province (province FE)
                             match2_nonpartisans, 
                             "party3" = rizzo2_nonpartisans$party3)
names(match2_nonpartisans)


# Run GenMatch function 
# IMPORTANT NOTE: 
  # the weight matrix computed by this code is available in the folder "genetic-matching-output-stored". 
  # To load this weight matrix, omit the GenMatch code and comment out the line below starting with "load(file = "genetic-matching-output-stored/..."

# Parallel cluster for faster computation
nCores<-detectCores()-1
pcores<-makeCluster(nCores)

# Computation takes about 60 minutes
# Solution Found Generation 30
# Number of Generations Run 81
set.seed(1)
gm.out2_nonpartisans <-	GenMatch(Tr = match2_nonpartisans$Tr, 
                                 # Include only covariates (and linearized estimated propensity scores)
                                 X = match2_nonpartisans[, c(6:23)], 
                                 pop.size = 5000,
                                 wait.generations = 50, 
                                 cluster=pcores)
stopCluster(pcores)

## save GenMatch output -- Or comment out the "load(file = ..." line to load the weight matrix already computed
save(gm.out2_nonpartisans, file = "genetic-matching-output/gen-match-output-supreme-nonpartisans.RData")
#load(file = "genetic-matching-output-stored/gen-match-output-supreme-nonpartisans.RData")

names(match2_nonpartisans)

# Use Match() to obtain dataset of matched observations
mout2_nonpartisans <- Match(Tr = match2_nonpartisans$Tr, 
                            # Include only covariates (and linearized estimated propensity scores)
                            X = match2_nonpartisans[, c(6:23)], 
                            Weight.matrix = gm.out2_nonpartisans,
                            ties=T,
                            replace=T)

# Vectors of matched control and treated observations
sel <- c(mout2_nonpartisans$index.treated, mout2_nonpartisans$index.control)
# Create dataset of matches
GM_nonpartisans_sup <- match2_nonpartisans[sel,]
# Add weights
GM_nonpartisans_sup$w <- c(mout2_nonpartisans$weights, mout2_nonpartisans$weights)

##  GM + WLS with bias adjustment
m_GM_nonpartisans_sup <- lm(f_GM_nonpartisans, data = GM_nonpartisans_sup, weights = w)

### Save models for tables and figure
GM_nonpartisans <- list("GM_nonpartisans_lower" = m_GM_nonpartisans_low, "GM_nonpartisans_supreme" = m_GM_nonpartisans_sup, 
                        "GM_nonpartisans_low" = GM_nonpartisans_low, "GM_nonpartisans_sup" = GM_nonpartisans_sup)
save(GM_nonpartisans, file = "models/GM-nonpartisans-covariates.RData")


### Prep data for table and figure

# Clean environment but keep data
keep <- c("rizzo", "rizzo1_lim", "rizzo2_lim", "rizzo1_ext", "rizzo2_ext")
rm(list = setdiff(ls(), keep))

# Call OLS models
load("models/OLS-nonpartisans-covariates.RData")
# Call entropy balancing binary models
load("models/EB-nonpartisans-covariates.RData")
# Call genetic matching models
load("models/GM-nonpartisans-covariates.RData")

names(OLS_nonpartisans)
names(EB_nonpartisans)
names(GM_nonpartisans)

# Lower Court models (limited set of covariates)
m1 <- OLS_nonpartisans[["OLS_nonpartisans_lower"]] # OLS model
rizzo1_nonpartisans <- OLS_nonpartisans[["rizzo1_nonpartisans"]] # OLS model
m2 <- EB_nonpartisans[["EB_nonpartisans_lower"]] # EB model
EB_nonpartisans_low <- EB_nonpartisans[["EB_nonpartisans_low"]] # EB dataset
m3 <- GM_nonpartisans[["GM_nonpartisans_lower"]] # GM model
GM_nonpartisans_low <- GM_nonpartisans[["GM_nonpartisans_low"]] # GM dataset

# Supreme Court models (limited set of covariates)
m4 <- OLS_nonpartisans[["OLS_nonpartisans_supreme"]] # OLS model
rizzo2_nonpartisans <- OLS_nonpartisans[["rizzo2_nonpartisans"]] # OLS model
m5 <- EB_nonpartisans[["EB_nonpartisans_supreme"]] # EB model
EB_nonpartisans_sup <- EB_nonpartisans[["EB_nonpartisans_sup"]] # EB dataset
m6 <- GM_nonpartisans[["GM_nonpartisans_supreme"]] # GM model
GM_nonpartisans_sup <- GM_nonpartisans[["GM_nonpartisans_sup"]] # GM dataset

## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = ~ city + date, type = "HC1"))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = ~ city + date, type = "HC1"))[,2]
se3 <- coeftest(m3, vcovCL(m3, cluster = ~ city + date, type = "HC1"))[,2]
se4 <- coeftest(m4, vcovCL(m4, cluster = ~ city + date, type = "HC1"))[,2]
se5 <- coeftest(m5, vcovCL(m5, cluster = ~ city + date, type = "HC1"))[,2]
se6 <- coeftest(m6, vcovCL(m6, cluster = ~ city + date, type = "HC1"))[,2]

## Compute means and SDs for the outcome
Y_bar <- round(c(mean(m1$resid + m1$fitted.values), 
                 mean(m2$resid + m2$fitted.values),
                 mean(m3$resid + m3$fitted.values),
                 mean(m4$resid + m4$fitted.values),
                 mean(m5$resid + m5$fitted.values),
                 mean(m6$resid + m6$fitted.values)),3)
Y_sd <- round(c(sd(m1$resid + m1$fitted.values), 
                sd(m2$resid + m2$fitted.values),
                sd(m3$resid + m3$fitted.values),
                sd(m4$resid + m4$fitted.values),
                sd(m5$resid + m5$fitted.values),
                sd(m6$resid + m6$fitted.values)),3)


## Create table
nonpartisans_tab <- stargazer(m1, m2, m3, m4, m5, m6,
                              se=list(se1, se2, se3, se4, se5, se6),
                              title="Results including Nonpartisans", align=TRUE,
                              dep.var.labels.include = FALSE, 
                              dep.var.caption = "",
                              label = "tab:nonpartisans",
                              column.labels = c("\\textbf{Lower Court}",
                                                "\\textbf{Supreme Court}"),
                              column.separate = c(3, 3),
                              keep = c("Tr", "party3", "Constant"),
                              covariate.labels = c("Court Ruling","Government Supporter", 
                                                   "Nonpartisan",
                                                   "C. Ruling $\\times$ Gov. Supporter", 
                                                   "C. Ruling $\\times$ Nonpartisan"),
                              star.char = c("+", "*", "**", "***"),
                              star.cutoffs = c(.1, .05, .01, .001),
                              notes.append=FALSE, notes.align = "l", notes.label = "",
                              omit.stat=c("f", "ser", "rsq"),
                              header = FALSE,
                              no.space = TRUE,
                              notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Outcome: Trust in the Judiciary ($0=$ ``A little\"/``None\"; $1=$ ``A lot\"/``Some\"). Robust standard errors clustered by city and date of survey interview. Controls: \\textit{Age}, \\textit{Female}, \\textit{Education}, \\textit{SES}, \\textit{Subjective Income}, \\textit{Class}, \\textit{Religion}. Models 2 and 4 employ entropy balance weights (Hainmueller 2012). Models 3 and 6 employ multivariate matching (Sekhon 2011) with optimal balance weights computed using the genetic matching algorithm by Diamond and Sekhon (2013). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"),
                              table.placement = "H",
                              add.lines = list(c("\\midrule Mean(Trust)", Y_bar),
                                               c("sd(Trust)", Y_sd),
                                               c("\\midrule Controls?",
                                                 "\\multicolumn{1}{c}{\\checkmark}", 
                                                 "\\multicolumn{1}{c}{\\checkmark}",
                                                 "\\multicolumn{1}{c}{\\checkmark}",
                                                 "\\multicolumn{1}{c}{\\checkmark}",
                                                 "\\multicolumn{1}{c}{\\checkmark}", 
                                                 "\\multicolumn{1}{c}{\\checkmark}"),
                                               c("Province FE?",
                                                 "\\multicolumn{1}{c}{\\checkmark}", 
                                                 "\\multicolumn{1}{c}{\\checkmark}",
                                                 "\\multicolumn{1}{c}{\\checkmark}",
                                                 "\\multicolumn{1}{c}{\\checkmark}",
                                                 "\\multicolumn{1}{c}{\\checkmark}", 
                                                 "\\multicolumn{1}{c}{\\checkmark}"))
)
# Format table for publication
nonpartisans_tab
nonpartisans_tab[4] <- "\\tabcolsep=8pt  \\label{tab:main}  \\resizebox{\\linewidth}{!}{%"
nonpartisans_tab[5] <- "\\begin{tabular}{l*{6}{d{1.3}}}"
nonpartisans_tab[6] <- "\\toprule & \\multicolumn{3}{c}{\\textbf{Lower Court}} & \\multicolumn{3}{c}{\\textbf{Supreme Court}} \\\\ \\cmidrule(r){2-4} \\cmidrule(l){5-7}"
nonpartisans_tab[7] <- " "
nonpartisans_tab[8] <- " "
nonpartisans_tab[9] <- "& \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} & \\multicolumn{1}{c}{OLS} & \\multicolumn{1}{c}{EB+WLS} & \\multicolumn{1}{c}{GM+WLS} \\\\ & \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} & \\multicolumn{1}{c}{(5)} & \\multicolumn{1}{c}{(6)}\\\\"
nonpartisans_tab[10] <- "\\midrule"
nonpartisans_tab[23] <- " "
nonpartisans_tab[30] <- " "
nonpartisans_tab[31] <- "\\bottomrule"
nonpartisans_tab[33] <- "\\end{tabular} }"
nonpartisans_tab

sink("tab/results-nonpartisans.tex")
cat(nonpartisans_tab, sep="\n")
sink()


###########################################
# Appendix: Figure H1.1

# Compute vcov matrices
vcov1 <- vcovCL(m1, cluster = ~ city + date, type = "HC1")
vcov2 <- vcovCL(m2, cluster = ~ city + date, type = "HC1")
vcov3 <- vcovCL(m3, cluster = ~ city + date, type = "HC1")
vcov4 <- vcovCL(m4, cluster = ~ city + date, type = "HC1")
vcov5 <- vcovCL(m5, cluster = ~ city + date, type = "HC1")
vcov6 <- vcovCL(m6, cluster = ~ city + date, type = "HC1")

data_fig <- rbind(
  ## Lower court
  cbind(as.data.frame(avg_comparisons(m1, variable = "Tr", by = "party3", 
                                      vcov = vcov1))[,3:10], 
        as.data.frame(avg_comparisons(m1, variable = "Tr", by = "party3", 
                                      vcov = vcov1, conf_level = 0.9))[,9:10], 
        "model" = "OLS"), 
  cbind(as.data.frame(avg_comparisons(m2, variable = "Tr", by = "party3", 
                                      vcov = vcov2))[,3:10], 
        as.data.frame(avg_comparisons(m2, variable = "Tr", by = "party3", 
                                      vcov = vcov2, conf_level = 0.9))[,9:10], 
        "model" = "EB"), 
  cbind(as.data.frame(avg_comparisons(m3, variable = "Tr", by = "party3", 
                                      vcov = vcov3))[,3:10], 
        as.data.frame(avg_comparisons(m3, variable = "Tr", by = "party3", 
                                      vcov = vcov3, conf_level = 0.9))[,9:10], 
        "model" = "GM"),
  ## Supreme Court
  cbind(as.data.frame(avg_comparisons(m4, variable = "Tr", by = "party3", 
                                      vcov = vcov4))[,3:10], 
        as.data.frame(avg_comparisons(m4, variable = "Tr", by = "party3", 
                                      vcov = vcov4, conf_level = 0.9))[,9:10], 
        "model" = "OLS"), 
  cbind(as.data.frame(avg_comparisons(m5, variable = "Tr", by = "party3", 
                                      vcov = vcov5))[,3:10], 
        as.data.frame(avg_comparisons(m5, variable = "Tr", by = "party3", 
                                      vcov = vcov5, conf_level = 0.9))[,9:10], 
        "model" = "EB"), 
  cbind(as.data.frame(avg_comparisons(m6, variable = "Tr", by = "party3", 
                                      vcov = vcov6))[,3:10], 
        as.data.frame(avg_comparisons(m6, variable = "Tr", by = "party3", 
                                      vcov = vcov6, conf_level = 0.9))[,9:10], 
        "model" = "GM")
)

names(data_fig)[9:10] <- c("conf.low90", "conf.high90")

data_fig$Tr <- NA
data_fig$Tr[1:9] <- "lower"
data_fig$Tr[10:18] <- "supreme"

# Reorder first differences to ease visual comparison in plot
data_fig <- data_fig[order(match(data_fig$model, c("OLS", "EB", "GM"), nomatch = 4), 
                           match(data_fig$party3, c("out", "non", "co"), nomatch = 4), 
                           data_fig$Tr
), ]

## Set common features across panels
ylim <- c(-max(abs(min(data_fig$conf.low)), abs(max(data_fig$conf.high))), 
          max(abs(min(data_fig$conf.low)), abs(max(data_fig$conf.high)))) # range y axis
xlim <- c(0.9, 1.7)
xticks <- c(1, 1.3, 1.6) # ticks position
xlabels <- c("Opposition\nSupporters", "Non-\npartisans", "Government\nSupporters") # ticks labels
xseg <- c(0.95, 1.05, 1.25, 1.35, 1.55, 1.65) # x_i segments
pts <- xseg # point estimates position
leglabel <- c("Lower Court", "Supreme Court") # legend labels

yaxis <- expression(
  axis(side = 2, at = seq(-0.6,0.6,0.2), las = 1, labels = FALSE, 
       cex.axis = 1.15),
  text(x = 0.8, y = seq(-0.6, 0.6, 0.2), cex = 1.15, 
       labels = round(seq(-0.6, 0.6, 0.2),1), 
       srt = 90, 
       adj = 0.5, xpd = NA)
)


#png(file = "fig/png-figures/nonpartisans.png", width = 7, height = 2.65, units = "in", res = 600)
#tiff(file = "fig/tiff-figures/nonpartisans.tif", width = 7, height = 2.65, units = "in", res = 600)
pdf(file = "fig/nonpartisans.pdf",
    width = 7, # The width of the plot in inches
    height = 2.65) # The height of the plot in inches
par(mar=c(1.9, 3.5, 2, 1), oma=c(1, 0, 0, 0)) # Set up margins by number of lines
layout(matrix(1:3, ncol=3), # 3-panel figure
       widths=c(0.355, 0.3225,0.3225)) # relative widths (1st panel wider bc of ylab)

plot(1, 1, type = "n", xaxt = "n", yaxt = "n", 
     ylim = ylim,
     xlim = xlim,
     ylab = "", main = "OLS",
     xlab = "")
title(ylab = "Effect of Court Ruling", line = 2.5)

eval(yaxis)

axis(side = 1, at = xticks, 
     tick = FALSE,
     #tck = -0.02, 
     cex.axis = 1, labels = xlabels
     #, padj = -1
)

segments(x0=xseg, x1=xseg, 
         y0=data_fig$conf.low90[data_fig$model == "OLS"], 
         y1=data_fig$conf.high90[data_fig$model == "OLS"], 
         lwd = 3, col = c("black"))
segments(x0=xseg, x1=xseg, 
         y0=data_fig$conf.low[data_fig$model == "OLS"], 
         y1=data_fig$conf.high[data_fig$model == "OLS"], 
         lwd = 1.5, col = c("black"))
points(xseg, 
       data_fig$estimate[data_fig$model == "OLS"], 
       pch = c(21,24), cex =1.5,
       col = c("black"), 
       bg = c("white", "black"))

abline(h = 0, col = "red", lty = 2, lwd = 1.5)

legend("topright", cex = 1, pt.cex = 1.2,
       legend=leglabel, pch = c(21,24), 
       col = "black", pt.bg = c("white", "black"))

# Model 2
par(mar=c(1.9, 2, 2, 1))

plot(1, 1, type = "n", xaxt = "n", yaxt = "n", 
     ylim = ylim,
     #ylim = c(min(prot_eff$conf.low), max(prot_eff$conf.high)), 
     xlim = xlim,
     ylab = "", main = "Entropy Balancing + WLS",
     xlab = "")
title(ylab = "Effect of Court Ruling", line = 2.5)

eval(yaxis)

axis(side = 1, at = xticks, 
     tick = FALSE,
     #tck = -0.02, 
     cex.axis = 1, labels = xlabels
     #, padj = -1
)

segments(x0=xseg, x1=xseg, 
         y0=data_fig$conf.low90[data_fig$model == "EB"], 
         y1=data_fig$conf.high90[data_fig$model == "EB"], 
         lwd = 3, col = c("black"))
segments(x0=xseg, x1=xseg, 
         y0=data_fig$conf.low[data_fig$model == "EB"], 
         y1=data_fig$conf.high[data_fig$model == "EB"], 
         lwd = 1.5, col = c("black"))
points(xseg, 
       data_fig$estimate[data_fig$model == "EB"], 
       pch = c(21,24), cex =1.5,
       col = c("black"), 
       bg = c("white", "black"))

abline(h = 0, col = "red", lty = 2, lwd = 1.5)

## Model 3
plot(1, 1, type = "n", xaxt = "n", yaxt = "n", 
     ylim = ylim,
     xlim = xlim,
     ylab = "", main = "Genetic Matching + WLS",
     xlab = "")
title(ylab = "Effect of Court Ruling", line = 2.5)

eval(yaxis)

axis(side = 1, at = xticks, 
     tick = FALSE,
     cex.axis = 1, labels = xlabels
)

segments(x0=xseg, x1=xseg, 
         y0=data_fig$conf.low90[data_fig$model == "GM"], 
         y1=data_fig$conf.high90[data_fig$model == "GM"], 
         lwd = 3, col = c("black"))
segments(x0=xseg, x1=xseg, 
         y0=data_fig$conf.low[data_fig$model == "GM"], 
         y1=data_fig$conf.high[data_fig$model == "GM"], 
         lwd = 1.5, col = c("black"))
points(xseg, 
       data_fig$estimate[data_fig$model == "GM"], 
       pch = c(21,24), cex =1.5,
       col = c("black"), 
       bg = c("white", "black"))

abline(h = 0, col = "red", lty = 2, lwd = 1.5)

dev.off()


###########################################################################
########################## Google Trends Figures ##########################
############### Main text figure 1 and Appendix Figure B4.1 ###############
###########################################################################


### function to create transparent colors
### http://stackoverflow.com/questions/8047668/transparent-equivalent-of-given-color
makeTransparent = function(..., alpha=0.5) {
  
  if(alpha<0 | alpha>1) stop("alpha must be between 0 and 1")
  
  alpha = floor(255*alpha)  
  newColor = col2rgb(col=unlist(list(...)), alpha=FALSE)
  
  .makeTransparent = function(col, alpha) {
    rgb(red=col[1], green=col[2], blue=col[3], alpha=alpha, maxColorValue=255)
  }
  
  newColor = apply(newColor, 2, .makeTransparent, alpha=alpha)
  
  return(newColor)
  
}


###########################################
# Main text Figure 1 

## Judicial council
g <- gtrends(keyword = "Consejo de la Magistratura", 
             time = "2013-03-1 2013-06-30", 
             onlyInterest = TRUE,
             low_search_volume = TRUE,
             geo = "AR")$interest_over_time

g$hits <- as.numeric(replace(g$hits, g$hits == "<1", "0"))
class(g$hits)
g$group <- ifelse(g$keyword == "Consejo Magistratura", 2, 1)


color = "black"
linety <- "solid"

pdf(file = "fig/google-trends-judicial-council.pdf",
    width = 8, # The width of the plot in inches
    height = 4.5) # The height of the plot in inches
par(mar=c(3.5, 3.5, 2, 0), oma=c(1, 1, 1, 1)) # Set up margins by number of lines

plot(g$hits ~ g$date, type="n", main="", 
     ylab = "", xlab = "",
     yaxt = "n",
     ylim = c(-10,115))

title(main = "", line = 1)
title(xlab = "2013", line = 2.5)
title(ylab = "Search Hits", line = 2.5)

#plot each group in the for loop
number_of_groups <- as.numeric(max(unique(g$group)))
for (i in 1:number_of_groups){
  temp <- subset(g,  group==i )
  lines(temp$date, temp$hits, col="black", lwd = 1.5)
}

yticks <- c(0,20,40,60,80,100)
axis(side = 2, at=yticks, labels = c("0", "20", 
                                     "40", "60", 
                                     "80", "100"))

legend(as.POSIXct("2013-03-1"), 65,
       legend=c("Judicial Council"), 
       lty = 1, lwd = 1.5, col = "black", cex = 0.8, 
       bty = "n",
       title = "Search Term")

segments(x0=c(as.POSIXct("2013-04-09"), as.POSIXct("2013-04-25"), 
              as.POSIXct("2013-05-8"), 
              as.POSIXct("2013-05-27"), as.POSIXct("2013-06-11"), 
              as.POSIXct("2013-06-18")),
         y0=0,
         x1=c(as.POSIXct("2013-04-09"), as.POSIXct("2013-04-25"), 
              as.POSIXct("2013-05-8"), 
              as.POSIXct("2013-05-27"), as.POSIXct("2013-06-11"), 
              as.POSIXct("2013-06-18")),
         y1=102, lty = 2, lwd = 1.5)
text(as.POSIXct("2013-04-05"), 110,"4/9 President sends\nbill to Congress",
     cex = 0.75)
text(as.POSIXct("2013-04-23"), 110,"4/25 House \npasses bill", 
     cex = 0.75)
text(as.POSIXct("2013-05-07"), 110,"5/8 Senate \npasses bill", 
     cex = 0.75)
text(as.POSIXct("2013-05-24"), 110,"5/27 President \ncalls for elections", 
     cex = 0.75)
text(as.POSIXct("2013-06-10"), 110,"6/11 Lower\nCourt ruling",
     cex = 0.75)
text(as.POSIXct("2013-06-19"), 110,"6/18 Supreme\nCourt ruling",
     cex = 0.75, adj = c(0.1))

polygon(x = c(as.POSIXct("2013-06-01"), 
              as.POSIXct("2013-06-01"),
              as.POSIXct("2013-06-30"),
              as.POSIXct("2013-06-30")), 
        y = c(-1,80,80,-1), 
        col = makeTransparent("grey", alpha = .3), 
        border = NA, lwd = 2)

legend(as.POSIXct("2013-05-28"), 0,
       legend=c("Latinobarómetro Survey"), 
       cex = 0.8, 
       bty = "n")

dev.off()


###########################################
# Appendix Figure B4.1 

## Judicial council and Ruling Courts (Latinobarometer Survey)

g2 <- gtrends(keyword = c("Consejo de la Magistratura", 
                          "Servini", "Corte Suprema"), 
              time = "2013-05-31 2013-07-01", 
              geo = "AR", 
              onlyInterest = TRUE)$interest_over_time

g2$hits <- as.numeric(replace(g2$hits, g2$hits == "<1", "0"))
class(g2$hits)
g2$group <- ifelse(g2$keyword == "Consejo de la Magistratura", 1, 
                   ifelse(g2$keyword == "Servini", 2, 3))


color = c("black", "#F1A340","#998EC3")
linety <- c(2,1,6)

pdf(file = "fig/google-trends-appendix.pdf",
    width = 8, # The width of the plot in inches
    height = 4.5) # The height of the plot in inches
par(mar=c(3.5, 3.5, 2, 0), oma=c(1, 1, 1, 1)) # Set up margins by number of lines

plot(g2$hits ~ g2$date, type="n", main="", 
     ylab = "", xlab = "",
     yaxt = "n",
     ylim = c(0,115))

title(main = "Search Activity (Latinobarómetro Survey)", line = 1)
title(xlab = "2013", line = 2.5)
title(ylab = "Search Hits", line = 2.5)

yticks <- c(0,20,40,60,80,100)
axis(side = 2, at=yticks, labels = c("0", "20", 
                                     "40", "60", 
                                     "80", "100"))

#plot each group in the for loop
number_of_groups <- as.numeric(max(unique(g2$group))) 
for (i in 1:number_of_groups){
  temp <- subset(g2,  group==i )
  lines(temp$date, temp$hits, col=color[i], lwd = 2, 
        lty = linety[i])
}

legend(1369851264, 97,
       legend=c(
         "Judicial Council", 
         "Servini", "Supreme Court"), 
       lty = linety, lwd = 2, col = color, cex = 0.8, 
       bty = "n",
       title = "Search Term")

segments(x0=c(1370909700,1371511800),
         y0=0,
         x1=c(1370909700,1371511800),
         y1=101, lty = 1, lwd = 1.5, col = "gray")
text(as.POSIXct("2013-06-11"), 110,"6/11 Lower\nCourt ruling",
     cex = .8)
text(as.POSIXct("2013-06-18"), 110,"6/18 Supreme\nCourt ruling",
     cex = .8)

dev.off()



############################################################################################################
############################################### Appendix B1 ################################################
#### Case Selection: Argentina's Institutional and Public Opinion Indicators in Comparative Perspective ####
############################################################################################################


###########################################
# Figure B1.1: V-Dem Indicators

## Load the Varieties of Democracy (V-Dem) dataset
vdem <- vdemdata::vdem

# Indicators
# High court independence (higher values = more independence)
vdem$vdem_ind <- vdem$v2juhcind
# Lower court independence (higher values = more independence)
vdem$vdem_ind_lc <- vdem$v2juncind
# purges/removals (higher values = more purges)
vdem$vdem_purge <- vdem$v2jupurge*(-1)
# Compliance with high court (higher values = higher non-compliance)
vdem$vdem_compliance_hc <- vdem$v2juhccomp
# Compliance with judiciary (higher values = higher non-compliance)
vdem$vdem_compliance_jud <- vdem$v2jucomp*(-1)
# Liberal democracy index (higher values = more democratic)
vdem$vdem_libdem <- vdem$v2x_libdem

colors <- viridis::viridis(6)
col <- adjustcolor(colors, alpha.f = 0.3)

vdem_dat <- vdem[vdem$year > 1949,]

countries <- split(vdem_dat, vdem_dat$country_name)

arg <- countries[["Argentina"]]

## Judicial independence
lac <- aggregate(vdem_ind ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(vdem_ind ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(vdem_ind ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(vdem_ind ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(vdem_ind ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
jud_ind <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-hc-independence-TS.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0.5, 0.5))
# Initialize plot
plot(NULL, xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$vdem_ind, na.rm = T), 
                                                 max(vdem_dat$vdem_ind, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "High Court Independence")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$vdem_ind, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(jud_ind[['west']]$year, jud_ind[['west']]$vdem_ind, type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(jud_ind[['mena']]$year, jud_ind[['mena']]$vdem_ind, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(jud_ind[['ssa']]$year, jud_ind[['ssa']]$vdem_ind, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(jud_ind[['eeca']]$year, jud_ind[['eeca']]$vdem_ind, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(jud_ind[['lac']]$year, jud_ind[['lac']]$vdem_ind, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$vdem_ind, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

abline(v = 2013, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()

## Judicial independence (lower courts)
lac <- aggregate(vdem_ind_lc ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(vdem_ind_lc ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(vdem_ind_lc ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(vdem_ind_lc ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(vdem_ind_lc ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
jud_ind_lc <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-lc-independence-TS.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0.5, 0.5))
# Initialize plot
plot(NULL, xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$vdem_ind_lc, na.rm = T), 
                                                 max(vdem_dat$vdem_ind_lc, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Lower Court Independence")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$vdem_ind_lc, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(jud_ind_lc[['west']]$year, jud_ind_lc[['west']]$vdem_ind_lc, type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(jud_ind_lc[['mena']]$year, jud_ind_lc[['mena']]$vdem_ind_lc, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(jud_ind_lc[['ssa']]$year, jud_ind_lc[['ssa']]$vdem_ind_lc, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(jud_ind_lc[['eeca']]$year, jud_ind_lc[['eeca']]$vdem_ind_lc, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(jud_ind_lc[['lac']]$year, jud_ind_lc[['lac']]$vdem_ind_lc, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$vdem_ind_lc, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

abline(v = 2013, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()

## Compliance with High Court
lac <- aggregate(vdem_compliance_hc ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(vdem_compliance_hc ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(vdem_compliance_hc ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(vdem_compliance_hc ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(vdem_compliance_hc ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
compliance_hc <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-hc-compliance-TS.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0.5, 0.5))
# Initialize plot
plot(NULL, xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$vdem_compliance_hc, na.rm = T), 
                                                 max(vdem_dat$vdem_compliance_hc, na.rm = T)+0.5),
     yaxt = "n",
     xlab = "", ylab = "", main = "Compliance with High Court")

axis(side = 2, at = seq(-4, 4, 2), cex.axis = 1,
     #padj = 0.5, hadj = 1, 
     labels = seq(-4, 4, 2))

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$vdem_compliance_hc, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(compliance_hc[['west']]$year, compliance_hc[['west']]$vdem_compliance_hc, type = "l", 
      col = "black",
      lwd = 1.5, lty = 1)

lines(compliance_hc[['mena']]$year, compliance_hc[['mena']]$vdem_compliance_hc, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(compliance_hc[['ssa']]$year, compliance_hc[['ssa']]$vdem_compliance_hc, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(compliance_hc[['eeca']]$year, compliance_hc[['eeca']]$vdem_compliance_hc, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(compliance_hc[['lac']]$year, compliance_hc[['lac']]$vdem_compliance_hc, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$vdem_compliance_hc, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

abline(v = 2013, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))
dev.off()

## Compliance with judiciary
lac <- aggregate(vdem_compliance_jud ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(vdem_compliance_jud ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(vdem_compliance_jud ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(vdem_compliance_jud ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(vdem_compliance_jud ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
compliance_jud <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-compliance-jud-TS.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0.5, 0.5))
# Initialize plot
plot(NULL, xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$vdem_compliance_jud, na.rm = T), 
                                                 max(vdem_dat$vdem_compliance_jud, na.rm = T)+0.5),
     yaxt = "n",
     xlab = "", ylab = "", main = "Compliance with Judiciary")

axis(side = 2, at = seq(-4, 4, 2), cex.axis = 1,
     #padj = 0.5, hadj = 1, 
     labels = seq(-4, 4, 2))

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$vdem_compliance_jud, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(compliance_jud[['west']]$year, compliance_jud[['west']]$vdem_compliance_jud, type = "l", 
      col = "black",
      lwd = 1.5, lty = 1)

lines(compliance_jud[['mena']]$year, compliance_jud[['mena']]$vdem_compliance_jud, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(compliance_jud[['ssa']]$year, compliance_jud[['ssa']]$vdem_compliance_jud, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(compliance_jud[['eeca']]$year, compliance_jud[['eeca']]$vdem_compliance_jud, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(compliance_jud[['lac']]$year, compliance_jud[['lac']]$vdem_compliance_jud, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$vdem_compliance_jud, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

abline(v = 2013, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))
dev.off()

## Purges
lac <- aggregate(vdem_purge ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(vdem_purge ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(vdem_purge ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(vdem_purge ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(vdem_purge ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
purge <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-purge-TS.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0.5, 0.5))
# Initialize plot
plot(NULL, xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$vdem_purge, na.rm = T), 
                                                 max(vdem_dat$vdem_purge, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Judicial Purges")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$vdem_purge, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(purge[['west']]$year, purge[['west']]$vdem_purge, type = "l", col = "black", 
      lwd = 1.5, lty = 1)

lines(purge[['mena']]$year, purge[['mena']]$vdem_purge, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(purge[['ssa']]$year, purge[['ssa']]$vdem_purge, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(purge[['eeca']]$year, purge[['eeca']]$vdem_purge, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(purge[['lac']]$year, purge[['lac']]$vdem_purge, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$vdem_purge, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

abline(v = 2013, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))
dev.off()


## Liberal Democracy
lac <- aggregate(vdem_libdem ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(vdem_libdem ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(vdem_libdem ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(vdem_libdem ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(vdem_libdem ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
libdem <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-libdem-TS.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0.5, 0.5))
# Initialize plot
plot(NULL, xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$vdem_libdem, na.rm = T), 
                                                 max(vdem_dat$vdem_libdem, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Liberal Democracy")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$vdem_libdem, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(libdem[['west']]$year, libdem[['west']]$vdem_libdem, type = "l", col = "black", 
      lwd = 1.5, lty = 1)

lines(libdem[['mena']]$year, libdem[['mena']]$vdem_libdem, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(libdem[['ssa']]$year, libdem[['ssa']]$vdem_libdem, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(libdem[['eeca']]$year, libdem[['eeca']]$vdem_libdem, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(libdem[['lac']]$year, libdem[['lac']]$vdem_libdem, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$vdem_libdem, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

abline(v = 2013, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))
dev.off()


###########################################
# Figure B1.2: Trust in the Judiciary (Latinobarometro)

# Clean environment
rm(list = ls())

# Load latinobarometer data
latbar <- readRDS(file = "data/latinobarometro-all/latinobarometro-all.rds")


# Create binary measure of trust in the judiciary
table(latbar$judiciary_trust, useNA = "always")

latbar$trust_binary <- ifelse(latbar$judiciary_trust < 0.5, 0, 1)

# Check
table(latbar$judiciary_trust, latbar$trust_binary, useNA = "always")

table(latbar$country_name)

latbar <- subset(latbar, latbar$country_name != "Spain")

trust_D <- data.frame(
  country = names(tapply(latbar$trust_binary, latbar$country_name, mean, na.rm = TRUE)),
  mean = as.vector(tapply(latbar$trust_binary, latbar$country_name, mean, na.rm = TRUE))
)

trust_D
trust_D <- trust_D[order(trust_D$mean), ]
trust_D


pdf(file = "fig/latinobar-trust-95-2023.pdf",   
    width = 8, # The width of the plot in inches
    height = 7)

par(mar=c(3, 5, 2, 0.5), oma=c(0, 0.5, 0.5, 0))

colors <- rep("gray", nrow(trust_D))
colors[which(trust_D$country == "Argentina")] <- "black"

bar <- barplot(trust_D[,"mean"], horiz = TRUE, names.arg = rownames(trust_D),
               cex.axis = 1, las = 2, main = "Trust in the Judiciary (1995-2023)", 
               yaxt = "n", col = colors,
               xaxt = "n", 
               ylab = "",
               xlab = "",
               xlim = c(0, 1))

text(x = -0.02, # horizontal position of x labels
     y = bar, 
     labels = trust_D$country,
     adj = 1, # alignment (0=left, 0.5=center, 1=right)
     xpd = NA,
     cex = 1.1)  

axis(side = 1, at = seq(0,1,0.2), las=2, cex.axis = 1,
     padj = 0.5, hadj = 1, labels = FALSE, tcl=-0.3)

text(x = seq(0,1,0.2), # horizontal position of x labels
     y = -1.35, 
     labels = seq(0,1,0.2),
     adj = 0.5, # alignment (0=left, 0.5=center, 1=right)
     xpd = NA,
     cex = 1)     

mtext(side = 1, "Proportion of Respondents Trusting the Judiciary", cex = 1.1, 
      line = 1.6)

abline(v = mean(latbar$trust_binary, na.rm = TRUE), col = "darkred", lty = 1, lwd = 2.5)
abline(v = median(trust_D$mean, na.rm = TRUE), col = "darkblue", lty = 2, lwd = 2.5)

legend("right", legend = c("Mean (pooled)", "Median (across country estimates)"), cex = 1.2,
       lty = c(1,2), lwd = 2, col = c("darkred", "darkblue"), 
       bty = "n")

dev.off()


latbar13 <- subset(latbar, latbar$year == 2013)

trust_D13 <- data.frame(
  country = names(tapply(latbar13$trust_binary, latbar13$country_name, mean, na.rm = TRUE)),
  mean = as.vector(tapply(latbar13$trust_binary, latbar13$country_name, mean, na.rm = TRUE))
)

trust_D13
trust_D13 <- trust_D13[order(trust_D13$mean), ]
trust_D13

pdf(file = "fig/latinobar-trust-2013.pdf",   
    width = 8, # The width of the plot in inches
    height = 7)

par(mar=c(3, 5, 2, 0.5), oma=c(0, 0.5, 0.5, 0))

colors <- rep("gray", nrow(trust_D13))
colors[which(trust_D13$country == "Argentina")] <- "black"

bar <- barplot(trust_D13[,"mean"], horiz = TRUE, names.arg = rownames(trust_D13),
               cex.axis = 1, las = 2, main = "Trust in the Judiciary (2013)", 
               yaxt = "n", col = colors,
               xaxt = "n", 
               ylab = "",
               xlab = "",
               xlim = c(0, 1))

text(x = -0.02, # horizontal position of x labels
     y = bar, 
     labels = trust_D13$country,
     adj = 1, # alignment (0=left, 0.5=center, 1=right)
     xpd = NA,
     cex = 1.1)  

axis(side = 1, at = seq(0,1,0.2), las=2, cex.axis = 1,
     padj = 0.5, hadj = 1, labels = FALSE, tcl=-0.3)

text(x = seq(0,1,0.2), # horizontal position of x labels
     y = -1.35, 
     labels = seq(0,1,0.2),
     adj = 0.5, # alignment (0=left, 0.5=center, 1=right)
     xpd = NA,
     cex = 1)     

mtext(side = 1, "Proportion of Respondents Trusting the Judiciary", cex = 1.1, 
      line = 1.6)

abline(v = mean(latbar13$trust_binary, na.rm = TRUE), col = "darkred", lty = 1, lwd = 2.5)
abline(v = median(trust_D13$mean, na.rm = TRUE), col = "darkblue", lty = 2, lwd = 2.5)

legend("right", legend = c("Mean (pooled)", "Median (across country estimates)"), cex = 1.2,
       lty = c(1,2), lwd = 2, col = c("darkred", "darkblue"), 
       bty = "n")

dev.off()



############################################################################
################################ Appendix I ################################
#### Analyses addressing concerns about the Newspaper Frequency measure ####
############################################################################


# Clean environment
rm(list = ls())


###########################################
# Correlates of the Newspaper Frequency Measure
# Appendix: Figure I1.1 and Table I1.1

# Load data
load("data/rizzo.RData")

# Remove nonpartisans (as in main analyses)
newspaper <- rizzo[!is.na(rizzo$party2), ]

### Correlation between newspaper frequency and other covariates

# Newspaper frequency
table(newspaper$newspaper_freq, useNA = "always")
newspaper_freq <- newspaper$newspaper_freq

# Political knowledge
table(newspaper$know, useNA = "always")
know <- newspaper$know

# Education
table(newspaper$education, useNA = "always")
education <- newspaper$education

# Political interest
table(newspaper$polint, useNA = "always")
polint <- newspaper$polint

# Radio
radio <- newspaper$radio_freq

# Read books for study
book_studies <- newspaper$book_studies

# TV frequency
tv <- newspaper$TV_freq

corr <- cbind("News-\npaper\n\n" = newspaper_freq, "Political\nKnow.\n\n" = know, 
              "Educ.\n" = education, "Political\nInt.\n\n" = polint, 
              "Study\nBooks\n\n" = book_studies, "TV\n" = tv, "Radio\n" = radio)

out <- cor(corr, use = "complete.obs", method = "pearson")

out2 <- Hmisc::rcorr(as.matrix(corr))

flattenCorrMatrix <- function(cormat, pmat) {
  ut <- upper.tri(cormat)
  data.frame(
    row = rownames(cormat)[row(cormat)[ut]],
    column = rownames(cormat)[col(cormat)[ut]],
    cor  =(cormat)[ut],
    p = pmat[ut]
  )
}

round(out2$P, 4)
rownames(out2$r) <- c("News-\npaper", "Political\nKnow.", "Educ.", "Political\nInt.", 
                      "Study\nBooks", "TV", "Radio")

pdf(file = "fig/newspaper-correlations.pdf", width = 5, height = 5)
par(mar=c(0, 1, 0, 0), oma=c(0, 0.5, 0, 0))
corrplot(out2$r, method = "number", type = "lower", order = "original", 
         xpd = TRUE,
         tl.col = "black", tl.srt = 0, diag = FALSE, 
         bg = 'lightgray',
         cl.pos = "n", col = c("darkred", "darkblue"))
dev.off()

cor_tab <- flattenCorrMatrix(out2$r, out2$P)

cor_tab$row <- gsub("\n", " ", cor_tab$row)
cor_tab$column <- gsub("\n", " ", cor_tab$column)
cor_tab$row <- gsub("News- paper", "Newspaper Frequency", cor_tab$row)
cor_tab$row <- gsub("Political Know.", "Political Knowledge", cor_tab$row)
cor_tab$row <- gsub("Educ.", "Education", cor_tab$row)
cor_tab$row <- gsub("Political Int.", "Political Interest", cor_tab$row)
cor_tab$row <- gsub("TV", "TV Frequency", cor_tab$row)
cor_tab$row <- gsub("Radio", "Radio Frequency", cor_tab$row)
cor_tab$column <- gsub("News- paper", "Newspaper Frequency", cor_tab$column)
cor_tab$column <- gsub("Political Know.", "Political Knowledge", cor_tab$column)
cor_tab$column <- gsub("Educ.", "Education", cor_tab$column)
cor_tab$column <- gsub("Political Int.", "Political Interest", cor_tab$column)
cor_tab$column <- gsub("TV", "TV Frequency", cor_tab$column)
cor_tab$column <- gsub("Radio", "Radio Frequency", cor_tab$column)

cor_tab

## Format table
sink("tab/correlation-newspaper.tex")

cat("\\begin{table}[H]\n")
cat("\\centering\n")
cat("\\caption{Correlation Tests} \n")
cat("\\tabcolsep=12pt\n")
cat("\\label{tab:cor_newspaper}\n")
cat("\\begin{tabular}{ll*{2}{d{1.3}}}\n")
cat("\\toprule\n")
cat("\\multicolumn{1}{l}{Variable 1} & ",
    "\\multicolumn{1}{l}{Variable 2} & ",
    "\\multicolumn{1}{c}{Pearson's $r$} & ",
    "\\multicolumn{1}{c}{$p$-value} \\\\\n")
cat("\\midrule\n")

# Loop through each row
for (i in 1:nrow(cor_tab)) {
  var1 <- cor_tab$row[i]
  var2 <- cor_tab$column[i]
  r <- sprintf("%.3f", cor_tab$cor[i])
  p <- if (cor_tab$p[i] < 0.001) "<0.001" else sprintf("%.3f", cor_tab$p[i])
  
  cat(sprintf("%s & %s & %s & %s \\\\\n", var1, var2, r, p))
}

cat("\\bottomrule\n")
cat("\\end{tabular}\n")
cat("\\end{table}\n")

sink()

###########################################
# I1.2 Patterns of Newspaper Consumption among Argentines

# Clean environment
rm(list = ls())

# Load SInCA data
sinca <- read.csv("data/sinca/sinca.csv")

# See codebook at https://datos.cultura.gob.ar/dataset/251c2ac2-e670-451c-9dbf-a4212af225b5/resource/84d3754e-583d-446d-b7d7-ca8bca3a0c38/download/metodologia-base-homologada.pdf

# Age 
names(table(sinca$GRUPOS_EDAD, useNA = "always"))

# NOTI1 (read any news, any format): "Durante el último año, ¿leyó noticias en diarios en papel, páginas de internet o redes sociales?"
# "During the last year, did you read news in print newspapers, on internet websites, or on social media?"
names(table(sinca$NOTI1, useNA = "always"))

# NOTI3.1 (print newspaper frequency): "Durante el último año, ¿con qué frecuencia… leyó noticias en diarios en papel?"
# "During the last year, how often... did you read news in print newspapers?"
names(table(sinca$NOTI3.1, useNA = "always"))

# 2013 data
sinca13 <- sinca[sinca$EDICION == 2013 
                 # Exclude younger than 18 or missing age
                 & !(sinca$GRUPOS_EDAD %in% c("", "13 A 17 ANIOS"))
                 # Exclude missing frequency
                 & sinca$NOTI1 != ""
                 ,]
# Check
table(sinca13$GRUPOS_EDAD, sinca13$NOTI1, useNA = "always")

#####
### Estimates from the SInCA 2013 report:

## 1. Most frequently consumed sections (p. 26)
# Whole newspaper: 29%
# National politics: 15%
# Op-ed (Artículos de opinión): 4%

## 2. News consumptions by age group (p. 27).
# Note that the number of respondents (N) comes from the SInCA 2013 data
table(sinca13$GRUPOS_EDAD, useNA = "always")

# 18-19 (N=904)
# Whole newspaper: 21%
# National politics: 14%
# Op-ed: 5%
# total: 40%

# 30-49: (N=932)
# Whole newspaper: 31%
# National politics: 18%
# Op-ed: 4%
# total: 53%

# 50-64: (N=614)
# Whole newspaper: 40%
# National politics: 19%
# Op-ed: 4%
# total: 63%

# >=65: (N=435)
# Whole newspaper: 39%
# National politics: 16%
# Op-ed: 3%
# total: 58%

# Adults (18 or older) having reported consuming
# 0.40*904
# 0.53*932
# 0.63*614
# 0.58*435
print(paste0("Proportion of adults (18 or older) who reported reading content about politics: ", 
             round((0.40*904 + 0.53*932 + 0.63*614 + 0.58*435)/nrow(sinca13), 3)
))


###########################################
# Appendix: Figure I2.1 (Freedom of Expression and Press in Argentina)

# Clean environment
rm(list = ls())

## Load the Varieties of Democracy (V-Dem) dataset
vdem <- vdemdata::vdem

# Rename relevant variables (Higher values indicate higher scores for each metric)
vdem$media_bias <- vdem$v2mebias*(-1) # e.g., higher values = greater bias
vdem$media_critical <- vdem$v2mecrit
vdem$media_selfcensor <- vdem$v2meslfcen*(-1)
vdem$freedom_expression <- vdem$v2x_freexp_altinf
vdem$gov_censor_efforts <- vdem$v2mecenefm*(-1)
vdem$media_perspectives <- vdem$v2merange


colors <- viridis::viridis(6)
col <- adjustcolor(colors, alpha.f = 0.3)

vdem_dat <- vdem[vdem$year > 1989,]


countries <- split(vdem_dat, vdem_dat$country_name)

arg <- countries[["Argentina"]]

## Media bias
lac <- aggregate(media_bias ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(media_bias ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(media_bias ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(media_bias ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(media_bias ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
media_bias <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-media-bias.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0, 0.5))
# Initialize plot
plot(NULL, yaxt = "n",
     xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$media_bias, na.rm = T), 
                                           max(vdem_dat$media_bias, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Media Bias")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$media_bias, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(media_bias[['west']]$year, media_bias[['west']]$media_bias, type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(media_bias[['mena']]$year, media_bias[['mena']]$media_bias, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(media_bias[['ssa']]$year, media_bias[['ssa']]$media_bias, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(media_bias[['eeca']]$year, media_bias[['eeca']]$media_bias, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(media_bias[['lac']]$year, media_bias[['lac']]$media_bias, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$media_bias, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

axis(side = 2, at = seq(-3,3,1), las = 1, labels = seq(-3,3,1), 
     cex.axis = 1)

segments(x0=2013,x1=2013,y0=-35, y1=2, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()


## Print/broadcast media critical
lac <- aggregate(media_critical ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(media_critical ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(media_critical ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(media_critical ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(media_critical ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
media_critical <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-media-critical.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0, 0.5))
# Initialize plot
plot(NULL, yaxt = "n",
     xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$media_critical, na.rm = T), 
                                           max(vdem_dat$media_critical, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Media Critical")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$media_critical, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(media_critical[['west']]$year, media_critical[['west']]$media_critical, type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(media_critical[['mena']]$year, media_critical[['mena']]$media_critical, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(media_critical[['ssa']]$year, media_critical[['ssa']]$media_critical, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(media_critical[['eeca']]$year, media_critical[['eeca']]$media_critical, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(media_critical[['lac']]$year, media_critical[['lac']]$media_critical, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$media_critical, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

axis(side = 2, at = seq(-3,3,1), las = 1, labels = seq(-3,3,1), cex.axis = 1)

segments(x0=2013,x1=2013,y0=-35, y1=2.8, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()


## Freedom of expression index
lac <- aggregate(freedom_expression ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(freedom_expression ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(freedom_expression ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(freedom_expression ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(freedom_expression ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
freedom_expression <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-freedom-expression.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0, 0.5))
# Initialize plot
plot(NULL, yaxt = "n",
     xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$freedom_expression, na.rm = T), 
                                           max(vdem_dat$freedom_expression, na.rm = T)+0.2),
     xlab = "", ylab = "", main = "Freedom of Expression Index")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$freedom_expression, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(freedom_expression[['west']]$year, freedom_expression[['west']]$freedom_expression, type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(freedom_expression[['mena']]$year, freedom_expression[['mena']]$freedom_expression, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(freedom_expression[['ssa']]$year, freedom_expression[['ssa']]$freedom_expression, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(freedom_expression[['eeca']]$year, freedom_expression[['eeca']]$freedom_expression, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(freedom_expression[['lac']]$year, freedom_expression[['lac']]$freedom_expression, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$freedom_expression, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

axis(side = 2, at = seq(0,1,0.2), las = 1, labels = seq(0,1,0.2), cex.axis = 1)

segments(x0=2013,x1=2013,y0=-35, y1=1, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()


## Media self-censorship
lac <- aggregate(media_selfcensor ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(media_selfcensor ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(media_selfcensor ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(media_selfcensor ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(media_selfcensor ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
media_selfcensor <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-media-self-censorship.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0, 0.5))
# Initialize plot
plot(NULL, yaxt = "n",
     xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$media_selfcensor, na.rm = T), 
                                           max(vdem_dat$media_selfcensor, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Media Self-Censorship")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$media_selfcensor, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(media_selfcensor[['west']]$year, media_selfcensor[['west']]$media_selfcensor, type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(media_selfcensor[['mena']]$year, media_selfcensor[['mena']]$media_selfcensor, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(media_selfcensor[['ssa']]$year, media_selfcensor[['ssa']]$media_selfcensor, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(media_selfcensor[['eeca']]$year, media_selfcensor[['eeca']]$media_selfcensor, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(media_selfcensor[['lac']]$year, media_selfcensor[['lac']]$media_selfcensor, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$media_selfcensor, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

axis(side = 2, at = seq(-3,3,1), las = 1, labels = seq(-3,3,1), cex.axis = 1)

segments(x0=2013,x1=2013,y0=-35, y1=2, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()



## Government censorship effort
lac <- aggregate(gov_censor_efforts ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(gov_censor_efforts ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(gov_censor_efforts ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(gov_censor_efforts ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(gov_censor_efforts ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
gov_censor_efforts <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-gov-censor-efforts.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0, 0.5))
# Initialize plot
plot(NULL, yaxt = "n",
     xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$gov_censor_efforts, na.rm = T), 
                                           max(vdem_dat$gov_censor_efforts, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Government Censorship Efforts")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$gov_censor_efforts, type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(gov_censor_efforts[['west']]$year, gov_censor_efforts[['west']]$gov_censor_efforts, type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(gov_censor_efforts[['mena']]$year, gov_censor_efforts[['mena']]$gov_censor_efforts, type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(gov_censor_efforts[['ssa']]$year, gov_censor_efforts[['ssa']]$gov_censor_efforts, type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(gov_censor_efforts[['eeca']]$year, gov_censor_efforts[['eeca']]$gov_censor_efforts, type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(gov_censor_efforts[['lac']]$year, gov_censor_efforts[['lac']]$gov_censor_efforts, type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$gov_censor_efforts, type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

axis(side = 2, at = seq(-3,3,1), las = 1, labels = seq(-3,3,1), cex.axis = 1)

segments(x0=2013,x1=2013,y0=-35, y1=2, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()

## Print media perspectives (C) (v2merange)
lac <- aggregate(media_perspectives  ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 2, mean, na.rm = TRUE)

west <- aggregate(media_perspectives  ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 5, mean, na.rm = TRUE)
mena <- aggregate(media_perspectives  ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 3, mean, na.rm = TRUE)
ssa <- aggregate(media_perspectives  ~ year, 
                 data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                 subset = e_regionpol_6C == 4, mean, na.rm = TRUE)
eeca <- aggregate(media_perspectives  ~ year, 
                  data = vdem_dat[vdem_dat$country_name != "Argentina", ], 
                  subset = e_regionpol_6C == 1, mean, na.rm = TRUE)
media_perspectives  <- list(lac = lac, west = west, mena = mena, ssa = ssa, eeca = eeca)

pdf(file = "fig/v-dem-print-media-perspectives.pdf", width = 5, height = 3)
par(mar=c(2, 2, 2, 2), oma=c(0.5, 0.5, 0, 0.5))
# Initialize plot
plot(NULL, yaxt = "n",
     xlim = range(vdem_dat$year), ylim = c(min(vdem_dat$media_perspectives, na.rm = T), 
                                           max(vdem_dat$media_perspectives, na.rm = T)+0.5),
     xlab = "", ylab = "", main = "Media Perspectives")

# Plot each country's data
i <- 1
for (country in names(countries)) {
  country_data <- countries[[country]]
  lines(country_data$year, country_data$media_perspectives , type = "l", 
        col = adjustcolor("lightgray", alpha.f = 0.35), lwd = 1)
  i <- i + 1
}

lines(media_perspectives [['west']]$year, media_perspectives [['west']]$media_perspectives , type = "l", col = "black",
      lwd = 1.5, lty = 1)

lines(media_perspectives [['mena']]$year, media_perspectives [['mena']]$media_perspectives , type = "l", col = colors[3], 
      lwd = 1.5, lty = 1)

lines(media_perspectives [['ssa']]$year, media_perspectives [['ssa']]$media_perspectives , type = "l", col = colors[4], 
      lwd = 1.5, lty = 1)

lines(media_perspectives [['eeca']]$year, media_perspectives [['eeca']]$media_perspectives , type = "l", col = colors[5], 
      lwd = 1.5, lty = 1)

lines(media_perspectives [['lac']]$year, media_perspectives [['lac']]$media_perspectives , type = "l", col = colors[6], 
      lwd = 1.5, lty = 1)

lines(arg$year, arg$media_perspectives , type = "l", col = colors[1], 
      lwd = 1.75, lty = 2)

axis(side = 2, at = seq(-4,3,1), las = 1, labels = seq(-4,3,1), cex.axis = 1)

segments(x0=2013,x1=2013,y0=-35, y1=2.5, col = "darkred")

legend("topleft", legend = c("Argentina", "W. Eu./N. Am.", 
                             "MENA", "SSA", "EECA", "LAC"), 
       lty = c(2,1,1,1,1,1), lwd = 2, ncol = 3, bty = "n",
       cex = 0.75, col = c(colors[1], "black", colors[3:6]))

dev.off()



###############################################################################
################################# Appendix J ##################################
#### Analyses addressing concerns about the Trust in the Judiciary measure ####
###############################################################################


# Clean environment
rm(list = ls())


# Load Latinobarometer data
latbar <- readRDS(file = "data/latinobarometro-all/latinobarometro-all.rds")
# Load Lapop data
lapop <- readRDS(file = "data/lapop-all/lapop-all.rds")


######################
# 1. Correlation between judiciary and individual court items
# Appendix Table J2.1: Country and Pooled Correlations between Trust Items
######################

cor_pairs <- list(
  "Judiciary and Electoral Court" = list(vars = c("judiciary_trust", "electoral_court_trust"), data = latbar),
  "Justice System and Electoral Court" = list(vars = c("system", "elect_court"), data = lapop),
  "Justice System and High Court" = list(vars = c("system", "high_court"), data = lapop),
  "Justice System and Constitutional Court" = list(vars = c("system", "const_court"), data = lapop),
  "Justice System and Public Ministry" = list(vars = c("system", "public_ministry"), data = lapop)
)


get_country_correlations <- function(data, var1, var2) {
  split_data <- split(data, data$country_name)
  split_data <- Filter(function(df) {
    sum(complete.cases(df[[var1]], df[[var2]])) >= 2
  }, split_data)
  
  cor_results <- lapply(split_data, function(df) {
    complete_rows <- complete.cases(df[[var1]], df[[var2]])
    test <- cor.test(df[[var1]][complete_rows], df[[var2]][complete_rows], method = "pearson")
    round(test$estimate, 3)
  })
  
  setNames(unlist(cor_results), names(cor_results))
}

get_pooled_correlation <- function(data, var1, var2) {
  complete_rows <- complete.cases(data[[var1]], data[[var2]])
  test <- cor.test(data[[var1]][complete_rows], data[[var2]][complete_rows], method = "pearson")
  round(test$estimate, 3)
}

cor_list <- list()
pooled_row <- c("Pooled")

all_countries <- unique(unlist(lapply(cor_pairs, function(info) unique(info$data$country_name))))
cor_matrix <- data.frame(country_name = sort(all_countries), stringsAsFactors = FALSE)

for (pair_name in names(cor_pairs)) {
  vars <- cor_pairs[[pair_name]]$vars
  df   <- cor_pairs[[pair_name]]$data
  
  cors <- get_country_correlations(df, vars[1], vars[2])
  cor_matrix[[pair_name]] <- cors[match(cor_matrix$country_name, names(cors))]
  
  pooled_row <- c(pooled_row, get_pooled_correlation(df, vars[1], vars[2]))
}

cor_matrix <- rbind(cor_matrix, setNames(as.list(pooled_row), names(cor_matrix)))

for (col in 2:ncol(cor_matrix)) {
  cor_matrix[[col]] <- as.numeric(cor_matrix[[col]])
}

cor_matrix_fmt <- cor_matrix
cor_matrix_fmt[is.na(cor_matrix_fmt)] <- "\\multicolumn{1}{c}{--}"

latex_table <- xtable(cor_matrix_fmt,
                      caption = "Country and Pooled Correlations",
                      label = "tab:corr-all",
                      digits = 3)

header1 <- list(pos = list(0),
                command = paste0(
                  "\\toprule\n",
                  " & ",
                  "\\multicolumn{1}{c}{\\textbf{Latinobar\'ometro}} & ",
                  "\\multicolumn{4}{c}{\\textbf{AmericasBarometer}} & "
                ))

header <- list(pos = list(0),
               command = paste0(
                 "\\midrule\n",
                 "\\multicolumn{1}{c}{} & ",
                 "\\multicolumn{1}{c}{\\makecell{Judiciary\\\\Electoral Court}} & ",
                 "\\multicolumn{1}{c}{\\makecell{Justice System\\\\Electoral Court}} & ",
                 "\\multicolumn{1}{c}{\\makecell{Justice System\\\\High Court}} & ",
                 "\\multicolumn{1}{c}{\\makecell{Justice System\\\\Const. Court}} & ",
                 "\\multicolumn{1}{c}{\\makecell{Justice System\\\\Public Ministry}} \\\\ \n"
               ))

midrule_pos <- nrow(cor_matrix_fmt) - 1
midrule_line <- list(pos = list(midrule_pos), command = "\\midrule\n")

add_rows <- list(
  pos = c(header$pos, midrule_line$pos),
  command = c(header$command, midrule_line$command)
)

file_conn <- file("tab/cor-judiciary-individual-courts-all-raw.tex", "w")

print(latex_table,
      file = file_conn,
      type = "latex",
      include.rownames = FALSE,
      include.colnames = FALSE, 
      sanitize.text.function = identity,
      add.to.row = add_rows, 
      table.placement = "H", 
      caption.placement = "top")

close(file_conn)


####################
# 2. Predictors/Determinants of trust in judiciary/justice system and individual courts
# Appendix Table J2.2: Determinants of Trust in Judiciary/Judicial System and Specific Courts
#####################

# Clean environment but keep data
rm(list = setdiff(ls(), c("latbar", "lapop")))

## Latinobarometro data
covars_lat <- paste(c(
  "factor(court_exp_bribe)",
  "access_justice_equal",
  "courts_guilty", 
  "dem_preferable2",
  "dem_supp",
  "approval_exec",
  "age", 
  "income", 
  "education", 
  "factor(sex)"), 
  collapse = " + ")

## Model 1 (Trust in the Judiciary)
f_lat <- as.formula(paste0("judiciary_trust ~ ", covars_lat))
m1 <- lm(f_lat, data = latbar)

## LAPOP data
covars_lap <- paste(c(
  "court_exp", 
  "court_fair", 
  "dem_preferable2",
  "dem_supp",
  "approval_exec",
  "respect_pol_inst", 
  "proud_pol_sys",
  "support_pol_sys",
  "age", 
  "income", 
  "education", 
  "race_ethn", 
  "place_size",
  "sex0"), 
  collapse = " + ")

outcome <- c("system", "high_court", "const_court", "elect_court")

## Model 2 (Trust in the Judicial System)
f_lap <- as.formula(paste0(outcome[1], " ~ ", covars_lap))
m2 <- lm(f_lap, data = lapop)

## Model 3 (Trust in High Court)
f_lap <- as.formula(paste0(outcome[2], " ~ ", covars_lap))
m3 <- lm(f_lap, data = lapop)

f_lap <- as.formula(paste0(outcome[4], " ~ ", covars_lap))
m4 <- lm(f_lap, data = lapop)

## Compute cluster-robust standard errors
se1 <- coeftest(m1, vcovCL(m1, cluster = latbar[complete.cases(m1$model), 
                                                "cluster"]))[,2]
se2 <- coeftest(m2, vcovCL(m2, cluster = lapop[complete.cases(m2$model), 
                                               "cluster"]))[,2]
se3 <- coeftest(m3, vcovCL(m3, cluster = lapop[complete.cases(m3$model), 
                                               "cluster"]))[,2]
se4 <- coeftest(m4, vcovCL(m4, cluster = lapop[complete.cases(m4$model), 
                                               "cluster"]))[,2]

## Create main text table
tab_broader_specific <- stargazer(m1, m2, m3, m4,
                                  se=list(se1, se2, se3, se4),
                                  title="Determinants of Trust in Judiciary/Judicial System and Individual Courts", align=TRUE,
                                  dep.var.labels.include = FALSE, 
                                  dep.var.caption = "",
                                  label = "tab:reg-broader-specific-institutions",
                                  column.labels = c("Judiciary",
                                                    "Justice System",
                                                    "High Court", 
                                                    "Electoral Court"
                                  ),
                                  omit = c("age", 
                                           "income",
                                           "education", 
                                           "sex", 
                                           "race_ethn", 
                                           "place_size"),
                                  order = c(7, 8,       # democratic support covariates
                                            9,          # support for incumbent
                                            10, 11, 12, # Evaluation of Political System
                                            1, 2, 5,    # Experiential Judgments
                                            3, 4,  6    # Evaluation of Judicial System
                                  ),
                                  covariate.labels = c("Democracy Preferable", 
                                                       "Support for Democracy", 
                                                       "Approval of Executive", 
                                                       "Respect for Political System", 
                                                       "Proud of Political System", 
                                                       "Support for Political System",
                                                       "\\hspace{5mm} Bribe",
                                                       "\\hspace{5mm} No Bribe",
                                                       "Contact with Courts Last 12 Months", 
                                                       "Equal Access to Justice",
                                                       "Judicial System Punishes Guilty", 
                                                       "Courts Guarantee a Fair Trial" 
                                  ),
                                  star.char = c("+", "*", "**", "***"),
                                  star.cutoffs = c(.1, .05, .01, .001),
                                  notes.append=FALSE, notes.align = "l", notes.label = "",
                                  omit.stat=c("f", "ser", "rsq"),
                                  header = FALSE,
                                  no.space = TRUE,
                                  notes = c("\\small \\parbox[t]{\\textwidth}{\\textit{Note:} Robust standard errors clustered by region-survey year. Demographic Controls: \\textit{Age}, \\textit{Sex}, \\textit{Education}, \\textit{Income} (all models), \\textit{Race/Ethnicity}, \\textit{Size of Place} (models 2-4). \\hfill $^{+}p<0.1$; $^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}"), 
                                  table.placement = "H",
                                  add.lines = list(c("\\midrule Demographic Controls?",
                                                     "\\multicolumn{1}{c}{\\checkmark}", 
                                                     "\\multicolumn{1}{c}{\\checkmark}",
                                                     "\\multicolumn{1}{c}{\\checkmark}",
                                                     "\\multicolumn{1}{c}{\\checkmark}",
                                                     "\\multicolumn{1}{c}{\\checkmark}", 
                                                     "\\multicolumn{1}{c}{\\checkmark}"))
)
# Format table for publication
tab_broader_specific
tab_broader_specific[4] <- "\\tabcolsep=6pt  \\label{tab:reg-tab}  \\resizebox{\\linewidth}{!}{%"
tab_broader_specific[5] <- "\\begin{tabular}{l*{4}{d{1.3}}}"
tab_broader_specific[6] <- "\\toprule"
tab_broader_specific[7] <- " & \\multicolumn{2}{c}{\\textbf{Broader Institutions}} & \\multicolumn{2}{c}{\\textbf{Individual Courts}} \\\\ \\cmidrule(r){2-3} \\cmidrule(l){4-5}"
tab_broader_specific[9] <- "& \\multicolumn{1}{c}{(1)} & \\multicolumn{1}{c}{(2)} & \\multicolumn{1}{c}{(3)} & \\multicolumn{1}{c}{(4)} \\\\"
tab_broader_specific[10] <- "\\midrule \\textit{Democratic Support} & & & & \\\\ \\cmidrule(lr){1-1}"
tab_broader_specific[15] <- paste0("\\textit{Support for Incumbent} & & & & \\\\ \\cmidrule(lr){1-1}", tab_broader_specific[15])
tab_broader_specific[17] <- paste0("\\textit{Evaluation of Political System} & & & & \\\\ \\cmidrule(lr){1-1}", tab_broader_specific[17])
tab_broader_specific[23] <- paste0("\\textit{Experiential Judgements} & & & & \\\\ \\cmidrule(lr){1-1}", "Experience with Courts (ref.: No Contact) & & & & \\\\ ", tab_broader_specific[23])
tab_broader_specific[29] <- paste0("\\textit{Evaluation of Judicial System} & & & & \\\\ \\cmidrule(lr){1-1}", tab_broader_specific[29])
tab_broader_specific[37] <- ""
tab_broader_specific[41] <- ""
tab_broader_specific[42] <- "\\bottomrule"
tab_broader_specific[44] <- "\\end{tabular} }"

cat(tab_broader_specific, sep = '\n', file = "tab/reg-broader-specific-institutions.tex")

